为什么在这种情况下使用Interface over Abstract类?

时间:2012-04-13 15:33:24

标签: java inheritance interface

我在这里阅读博客文章:http://codeofdoom.com/wordpress/2009/02/12/learn-this-when-to-use-an-abstract-class-and-an-interface/

public interface Actor{
   Performance say(Line l);
}
public interface Director{
   Movie direct(boolean goodmovie);
}
public interface ActorDirector extends Actor, Director{
...
}

它说: 实际上,有演员也是导演。如果我们使用接口而不是抽象类。我们可以使用抽象类来实现相同的功能。不幸的是,替代方案需要最多 2 ^ n (其中n是属性的数量)可能的组合,以支持所有可能性。

问题:为什么抽象课在这里更好?为什么2 ^ n?

public abstract class ActorDirector implements Actor,Director{
}

4 个答案:

答案 0 :(得分:6)

您不能从多个类继承(抽象或不抽象),但可以实现多个接口

如果你要创建抽象类,那么每个组合都需要一个(n个属性:2 ^ n可能的组合) - 以确保每个组合都可以继承,如果需要的话。

如果使用接口,则只需定义n接口(每个属性一个)并根据需要实现它们。

答案 1 :(得分:1)

在决定是否需要Abstract课程时,您需要回答的问题很简单;

在实现这些接口之一的任何类之间共享的任何方法是否有任何常见的实现?如果是,那么您可以将该实施放在AbstractClass

如果是,那么您只需将两者合并为一个Interface,并让所有实现类提供其自定义的非共享实现。

要做到这两点肯定有争议。有一个超级接口,允许解决单继承限制,以及也具有该超级接口的Abstract实现,为任何方法的任何共享默认实现提供高内聚性。界面。

这些决定越容易,您获得的解决方案就越多。

答案 2 :(得分:1)

我认为你误解了这篇文章:作者并不认为抽象类在这种情况下更好 - 相反,他认为界面更适合。

2^n(或更准确地说2^n-1)而言,数字来自于认识到如果您有n正交行为合同,则可以2^n-1非 - 来自他们的空洞组合。如果使用接口将合同添加到实现它们的类中,则只需要与行为一样多的接口:用户将能够组合他选择实现的行为,最多2^n-1。如果您尝试使用抽象类实现相同的灵活性,那么最终您不仅会创建所需的实现,而且还会创建所有中间的实现,直到单个根,因为Java会让您只能一次继承一个类。

答案 3 :(得分:0)

继承有两个部分:

  1. 派生类可以将其父项的公共或受保护方法或字段视为自己的方法或字段。
  2. 派生类型对象可以在请求后者的大多数上下文中替换基类型对象。

实现接口的类只接收后一个好处,但是从抽象类继承的类可以实现两者。另一方面,有了这样的好处就产生了一个限制:因为只有一个类可以将另一个类的方法和字段视为自己的,所以只有一个类才能从一个抽象类继承。相比之下,一个类可以实现(因此可以替代)任意数量的接口。

不要担心抽象类的组合爆炸。假设一些车辆可以转向(例如CompactCar),其他车辆可以使用AttachFollower(例如RailwayLocomotive),而一些车辆可以同时执行(例如PickupTruck)。 PickupTruck应该可以满足需要Steer的车辆的代码,以及需要能够AttachFollower的车辆的代码。但是,如果SteerAttachFollower都是抽象类,则无法声明PickupTruck,因此一个实例可以执行这两个函数。最好的方法是定义一个'SteerableAndHitchable abstract class which inerits from可操纵的and includes a TrailerHitch member of type可附加的',但即使只有两种能力,这种东西也很狡猾。以类型安全的方式添加更多功能不仅需要爆炸数量的类;每个班级都需要不断增加的房产数量。