为什么使用抽象类而不是接口?

pw136qt2  于 2021-07-09  发布在  Java
关注(0)|答案(6)|浏览(512)

例如,一个房地产建筑商正在建造一个有许多公寓的公寓。除了卧室外,公寓里所有的房间都有相同的设计。卧室的设计留给那些想拥有公寓的人,即;对于不同的公寓,卧室可以有不同的设计。
我可以通过 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");
   }        

}

或者我可以使用 interface 而不是 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 上课?

6ju8rftf

6ju8rftf1#

如果您正在设计一个将被广泛使用的api,那么您将同时使用两种方法:一种是接口来表示通过实现类来实现的契约,另一种是抽象类,它部分实现了该接口,从而允许代码重用。
例如,考虑java的list:collections框架中的方法(例如collections.sort())是根据list接口编写的,list接口部分由抽象类abstractlist实现,而abstractlist又扩展到具体的实现linkedlist和arraylist。linkedlist和arraylist重用abstractlist中的代码,但这并不妨碍某些人编写自己的完全独立的list实现,然后使用collections.sort()对其进行排序。
也就是说,在很多情况下,这种方法可能会被过度使用。如果您正在构建的类型层次结构只在相对较小的范围内使用,那么通常只使用抽象类就可以了。如果您以后决定以后需要一个接口,那么修改它是一个相当轻松的重构任务。
抽象类确实有一些优点:
它们允许您使用包/受保护的修饰符指定抽象方法
它们有助于代码重用
通过在超类上使用抽象方法和final方法,它们允许您限制类的子类化方式,这在各种情况下都很有用(另请参见:模板模式)
在ide中引用类的代码通常更容易理解(在抽象类类型参数上单击“open declaration”通常比在接口类型参数上单击“open declaration”更有用)

p4tfgftt

p4tfgftt2#

不能扩展多个类,但可以实现多个接口
如果您需要经常更改您的设计,那么抽象类更好,因为任何更改都发生在抽象类中,子类中不需要强制实现。但如果接口有任何变化,就必须实现类的实现。

rqqzpn5f

rqqzpn5f3#

如果有一个类提供了派生类所需的某些功能,但每个派生类还需要其他功能的不同实现,那么抽象类提供了定义公共实现的方法,而使派生类所需的特定行为特定于每个派生类。

brtdzjyr

brtdzjyr4#

这取决于您的意图或用例。但一般来说,您应该更喜欢接口而不是抽象类(bloch的effectivejava中的第18项)。抽象类更脆弱,因为有人可能修改抽象类,从而改变从抽象类扩展而来的其他类的行为(这是一个常规语句)。
使用接口更灵活,因为如果您有bedroominterface和livingroominterface,那么您可以让flatinterface实现这两个接口,然后flat101实现类实现flatinterface(而不是从flat扩展然后实现一个接口)。这似乎更清楚,以后您可以有executiveflatinterface,它不仅有卧室和客厅,而且还有猜测室,然后flat102可以从中实现。
方案2是让公寓101从公寓延伸,然后公寓实现卧室接口和客厅接口。这实际上取决于你想做什么以及可能需要什么方法。

goqiplq2

goqiplq25#

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

ars1skjm

ars1skjm6#

我觉得这是泛化的手段;如果类的属性和行为在给定的包或模块中是公共的,那么抽象类是最有用的。鼓式制动器就是一个很好的例子;由于所有鼓式制动器的工作原理都是相同的,所以在使用鼓式制动器的所有车型中都可以继承这种特性。
用于接口;它更像是规范或契约,迫使你实现它的物种形成。让我们举一个建筑模型的例子,它有所有的物种,比如门,窗,电梯…。。但是,当你在实际建筑中实现模型时,我们需要保留窗口,但是内部行为是由(因为窗口可以是一个简单的窗口或一个滑动窗口,颜色和材质…)决定的
希望这有帮助!!

相关问题