8

例如,一个房地产建筑商正在建造一个带有许多公寓的公寓。除卧室外,公寓中的所有房间都具有相同的设计。卧室设计留给拥有公寓的人,即;床 房间可以针对不同的公寓进行不同的设计。

abstract我可以通过下面的类来实现这一点:

public abstract class Flat
{
    //some properties

    public void livingRoom(){
       //some code
    }

    public void kitchen(){
       //some code
    }

    public abstract void bedRoom();

    }
}

一个implementation类如下:

public class Flat101 extends Flat
{
    public void bedRoom() {
        System.out.println("This flat has a customized bedroom");
   }        

}

或者,我可以使用 aninterface而不是abstract类来实现相同的目的,如下所示:

class Flat
{
  public void livingRoom(){ 
       System.out.println("This flat has a living room");
  }

  public void kitchen(){
     System.out.println("This flat has a kitchen");
  } 
}

interface BedRoomInterface
{
  public abstract void bedRoom();
}

public class Flat101 extends Flat implements BedRoomInterface
{
   public void bedRoom() {
    System.out.println("This flat has a customized bedroom");
   }
}

现在的问题是:为此为什么要选择使用一个interface(或)我为什么要选择使用一个abstract类?

4

6 回答 6

6

这取决于您的意图或用例。但总的来说,您应该更喜欢接口而不是抽象类(Bloch 的 Effective Java 中的第 18 条)。抽象类更脆弱,因为有人可能会修改抽象类,从而改变从它扩展的其他类的行为(这是一般性陈述)。

使用接口更灵活,因为如果你有 BedroomInterface 和 LivingRoomInterface,那么你可以让 FlatInterface 实现这两个接口,然后 Flat101 实现类实现 FlatInterface(而不是从 Flat 扩展然后实现一个接口)。这看起来更清楚了,以后你可以有ExecutiveFlatInterface,它不仅有卧室和客厅,还有猜测空间,然后Flat102可以从中实现。

选项 2 是让 Flat101 从 Flat 扩展,然后 Flat 实现 BedroomInterface 和 LivingRoomInterface。这实际上取决于您想要做什么以及可能需要什么方法。

于 2012-08-25T05:14:51.347 回答
4

如果您正在设计一个将被广泛使用的 API,您将同时使用:一个接口来表达要通过实现类来实现的合同,以及一个抽象类,它部分实现该接口并因此允许代码重用.

例如,考虑 Java 的 List:Collections 框架中的方法(例如 Collections.sort())是根据 List 接口编写的,该接口部分由抽象类 AbstractList 实现,而抽象类又被扩展为具体实现 LinkedList和数组列表。LinkedList 和 ArrayList 重用来自 AbstractList 的代码,但这并不妨碍人们编写自己完全独立的 List 实现,然后使用 Collections.sort() 对其进行排序。

也就是说,在很多情况下,这种方法可能有点矫枉过正。如果您正在构建的类型层次结构仅在相对较小的范围内使用,则通常只使用抽象类就可以了。如果您稍后决定以后需要一个接口,那么它是一项非常轻松的重构任务来改变事物。

抽象类确实有一些优点:

  • 它们允许您使用 package/protected 修饰符指定抽象方法
  • 它们促进代码重用
  • 通过在超类上使用抽象方法和最终方法,它们允许您限制类子类化的方式,这在各种情况下都很有用(另请参见:模板模式)
  • 引用类的代码通常更容易在 IDE 中遵循(在抽象类类型参数上单击“打开声明”通常比在接口类型参数上更有用)
于 2012-08-26T04:59:12.403 回答
1

如果您有一个类提供派生类所需的某些功能,但每个派生类还需要其他功能的不同实现,那么抽象类提供了一种定义通用实现的方法,同时保留了派生类所需的特定行为特定于每个派生类。

于 2012-08-25T15:13:01.113 回答
0

我觉得是泛化手段;如果类的属性和行为在给定的包或模块中是通用的,则抽象类是最有用的。一个很好的例子是鼓式制动器。由于所有鼓式制动器的工作方式与在轮鼓内保持制动器的方式相同,因此这种行为可以在所有使用鼓式制动器的汽车中继承。

用于接口;它更像是规范或合同,迫使您实施其物种形成。让我们以建筑物模型为例,它具有门、窗、电梯等所有形态……但是当您将模型实施到实际建筑物中时,我们需要保留窗户,但内部行为由(因为寡妇可以是一个简单的寡妇或滑块窗口,颜色和材料......)

希望这可以帮助!!

于 2013-11-14T09:36:17.163 回答
0

我觉得当我们需要为多个类实现一些通用功能和一些抽象功能时,我们应该使用抽象类。如果我们看到 Flat 的例子,我们有一些通用设计和一些自定义设计,在这种用例中最好使用抽象而不是再次使用接口来实现自定义功能,并且使用抽象作为派生类不会创建作为普通派生类的额外实例。

于 2015-09-18T06:13:10.347 回答
-3

你不能扩展一个以上的类,但你可以实现多个接口

如果您需要经常更改设计,那么抽象类会更好,因为任何更改都发生在抽象类中,不需要在子类中强制实现。但是如果接口有任何变化,你必须实现实现类。

于 2012-08-25T05:19:39.427 回答