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

Java 为什么要创建抽象类和接口?,java,interface,abstract-class,multiple-inheritance,Java,Interface,Abstract Class,Multiple Inheritance,我本来想问有什么区别,但之前已经有人回答过了。但现在我问他们为什么会有这些不同?(我在这里讲的是java,我不知道这是否适用于其他语言) 这两件事似乎很相似。抽象类可以定义方法体,而接口不能,但可以继承多个接口。那么为什么他们(在他们编写Java时,我指的是Sun)没有做一件事,让您可以编写一个方法体,并且这种类型可以被一个类多次继承 无法编写方法体或多次扩展我没有看到的方法体有什么好处吗?多重继承更难在语言(编译器)中实现,因为它可能导致某些问题。这些问题以前在这里讨论过: 我一直认为这是Ja

我本来想问有什么区别,但之前已经有人回答过了。但现在我问他们为什么会有这些不同?(我在这里讲的是java,我不知道这是否适用于其他语言)

这两件事似乎很相似。抽象类可以定义方法体,而接口不能,但可以继承多个接口。那么为什么他们(在他们编写Java时,我指的是Sun)没有做一件事,让您可以编写一个方法体,并且这种类型可以被一个类多次继承


无法编写方法体或多次扩展我没有看到的方法体有什么好处吗?

多重继承更难在语言(编译器)中实现,因为它可能导致某些问题。这些问题以前在这里讨论过:


我一直认为这是Java中的一个折衷方案。接口允许一个类完成多个契约,而不必担心多重继承

>你描述的另一种方法是C++所使用的方法(例如MIXIN)。与此有关的“多重继承”问题相当复杂,在C++中有几个批评。

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


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

C++中的多重继承导致语义模糊。MI相当强大,但后果复杂


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

让它们成为一件事的是Scala的人使用Traits的路线,Traits是一个可以有方法并支持多重继承的接口


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

继承意味着继承父类的性质(含义)和责任(行为),而接口实现意味着履行契约(例如可序列化),这可能与班级的核心性质或责任无关

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

抽象类=is-a,策略=has-a

编辑:关于多重继承,请参见Pontus Gagge的答案。

考虑以下示例:

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

  public final void start()
  {
    switchPowerOn();
    sprinkleSomeFuel();
    ignite();
  }
}
抽象类可以帮助您拥有可以重写或不能重写的坚实基础方法,但在这些方法中,它使用抽象方法为您提供了执行特定操作的机会。在我的示例中,不同的发动机在如何打开电源、为点火装置喷洒燃油和进行点火方面有不同的实现方式,但是发动机的启动顺序始终保持不变


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

C++没有我所理解的混入。在运行时,可以将MIXIN添加到一个类(“添加日志记录行为到这个DBI实例”),这不是C++语言的核心部分。“菲利普,我不知道你的意思。Mixin经常被用在C++中,也许在Grady Booch的书中是最有名的。我想我们在“Mixin”的定义上不一致。没什么大不了的,走吧。@Philip我搜索了“运行时混合”,现在我明白你的意思了。动态语言很流行,在这方面我似乎落后了。老实说,我对mixin的体验仅限于Perl的
Moose::Role
s,它们也不完全相同。这些天来,我们有更多的可用概念,而不是用语言来描述它们。啊,我知道我肯定遗漏了一些东西,这是有道理的!