像许多其他语言一样,Java具有接口继承和实现继承。例如,Java类可以从另一个类继承,并且在那里具有实现的每个方法(假设父类不是抽象的)也会被继承。这意味着接口被继承以及此方法的实现。我可以覆盖它,但我不必这样做。如果我不覆盖它,则已继承该实现。
但是,我的类还可以“继承”(不是Java术语),只是一个没有实现的接口。实际上,在Java中,接口确实以这种方式命名,它们提供接口继承,但不继承任何实现,因为接口的所有方法都没有实现。
现在有这篇文章,说继承接口比实现更好,您可能想阅读它(至少是第一页的前半部分),它非常有趣。它避免了脆弱的基类问题等问题。到目前为止,所有这些都很有道理,文章中说的许多其他事情对我来说也很有道理。
让我感到困扰的是,实现继承意味着代码重用,这是面向对象语言最重要的属性之一。现在,如果Java没有类(就像Java教父James Gosling根据这篇文章的说法所希望的那样),它解决了实现继承的所有问题,但是您如何使代码重用成为可能?
例如,如果我有一个名为Car的类,它有一个方法move(),使得车辆移动。现在我可以为不同类型的车辆子类化Car,它们都是车辆,但都是Car的专业版本。一些可能以不同的方式移动,这些需要覆盖move(),但大多数只需保留继承的move(),因为它们像抽象父级Car一样移动。现在假设Java中只有接口,只有接口可以从彼此继承,类可以实现接口,但所有类都是final的,因此没有类可以从任何其他类继承。
当您拥有一个名为Interface Car和100个Car类时,如何避免需要为每个类实现相同的move()方法?除了实现继承之外,还存在哪些代码重用概念?
一些语言有Mixins。 Mixins是我的问题的答案吗?我读过它们,但我无法想象Mixins在Java世界中如何工作,以及它们是否真的能解决这个问题。
另一个想法是有一个仅实现Car接口的类,让我们称其为AbstractCar,并实现move()方法。现在其他车辆也实现了Car接口,内部它们创建了AbstractCar的实例,并通过调用其内部抽象Car上的move()方法来实现自己的move()方法。但这不会浪费资源(一个方法只调用另一个方法-好吧,JIT可以内联代码,但仍然)并使用额外的内存来保留内部对象吗? (毕竟,每个对象都需要比封装数据的总和更多的内存)此外,对于程序员来说,编写像这样的虚拟方法是否很尴尬?
public void move() {
abstractCarObject.move();
}
?
有没有更好的想法可以避免实现继承,但仍然能够轻松地重用代码?