为什么要创建抽象类和接口?

时间:2010-03-03 11:18:59

标签: java interface abstract-class multiple-inheritance

好吧,我想问一下有什么区别,但之前已经回答了。但现在我问他们为什么会产生这些差异呢? (我在这里谈论java,我不知道是否同样适用于其他语言)

这两件事似乎非常相似。抽象类可以定义方法体,而接口则不能,但可以继承多个接口。那么为什么他们(他们'我们的意思是Sun,当他们编写Java时)做了一件事你可以写一个方法体这个类型可以被一个类继承多次。 / p>

是否有一些优点是无法编写方法体,或者延伸多次我没有看到的?

7 个答案:

答案 0 :(得分:10)

因为允许类继承同一方法签名的多个实现会导致一个明显的问题,即应该在运行时使用哪一个。

Java通过仅支持接口的多重继承来避免这种情况。每个接口中声明的签名可以更容易组合(Java基本上使用所有方法的并集)

答案 1 :(得分:5)

C ++中的多重继承导致语义模糊,如diamond inheritance problem。 MI非常强大,但后果复杂。

使接口成为一种特殊情况也提高了概念作为信息隐藏手段和降低程序复杂性的可见性。在C ++中,定义纯抽象基础是成熟程序员的标志。在Java中,您会在程序员发展的早期阶段遇到它们。

答案 2 :(得分:3)

多重继承在一种语言(真正的编译器)中更难实现,因为它可能导致某些问题。这些问题之前已在此讨论过:What is the exact problem with multiple inheritance

我一直认为这是Java的妥协。接口允许类完成多个合同而不必担心多重继承。

答案 3 :(得分:2)

考虑这个例子:

public abstract class Engine
{
  public abstract void switchPowerOn();
  public abstract void sprinkleSomeFuel();
  public abstract void ignite();

  public final void start()
  {
    switchPowerOn();
    sprinkleSomeFuel();
    ignite();
  }
}

抽象类可以帮助您拥有可以或不可以覆盖的可靠基础方法,但在这些方法中,它使用抽象方法为您提供执行特定事物的机会。在我的示例中,不同的发动机具有不同的实施方式,如何打开电源,为点火喷洒一些燃料,以及点火,但发动机的起动序列始终保持不变。

这种模式被称为“表单模板方法”,坦率地说,这是我在Java中抽象类的唯一明智用法。

答案 4 :(得分:1)

让他们成为一件事就是Scala家伙使用Traits的路线,这是一个可以拥有方法并支持多重继承的接口。

对于我来说,我认为接口是干净的,因为它们只指定需求(按合同设计)而抽象类定义了常见的行为(实现),所以不同的工具用于不同的工作?接口可能允许在编译期间更有效地生成代码吗?

答案 5 :(得分:0)

您要描述的另一种方法是C ++使用的方法(例如mixins)。与这种“多重继承”相关的问题相当复杂,并且在C ++中有一些批评者。

答案 6 :(得分:0)

继承意味着您继承父类的性质(含义)和责任(行为),而接口实现意味着您履行合同(例如Serializable),可能与班级的核心性质或责任无关。

抽象类允许您定义一个您想要通用而不是直接可实现的性质,因为它必须是专用的。您知道如何执行某些高级任务(例如,根据某些参数做出决定),但您不知道某些较低级别操作的详细信息(例如,计算某些中间参数),因为它取决于实现选择。解决此问题的另一种方法是Strategy design pattern。它更灵活,允许运行时策略切换和Null行为,但它更复杂(并不总是需要运行时切换)。此外,您可能会失去一些含义&打字工具(多态和类型检查变得有点困难,因为策略是一个组件,而不是对象本身。)

Abstract class = is-a,策略= has-a

编辑:和多重继承一样,请参阅Pontus Gagge的回答。