抽象类与所有方法抽象和接口之间的区别?

2023-11-22

我有一次面试,面试官首先问我具有所有抽象方法的抽象类和接口之间有什么区别。

我回答说,如果以后需要继承一些东西,如果你已经扩展了一个类,你就无法继承。

然后,他说这是一种情况,永远不需要延长任何其他课程,你必须执行合同。在这种情况下,抽象类和接口哪个更好?

我告诉他你可以使用其中任何一个,但他不满意。我无法理解为什么 - 我相信这是开发人员/设计的选择。


接口代表契约的答案是不可接受的。 这就是我们给Junior的答案,因为如果没有太多的架构经验,也没有读过很多经典书籍,就很难清楚地弄清楚抽象类的本质和接口的本质之间的区别,这可能太复杂了。 任何抽象类public方法既充当契约,又充当接口。

不提供任何实现的抽象类在 99% 的情况下是对象的表示Role.
An 界面代表一个Role.
每个对象可能具有多个不同的角色,这些角色不应捆绑在一起,而应由相关对象组成。

我用这个例子来解释这一点:

你的面试官可能会说:
我有一个Robot可以行走并且Human那也可以走路。

因此,基于这个案例,他问你:在知道实现没有任何共同点的情况下,我应该将步行功能提取到抽象基类中还是接口中?

你认为......“哦,我知道是这样:在这种情况下,有一个带有抽象方法的抽象类walk(),那么显然与声明一个接口相同walk()方法。”
所以你的答案肯定是:“这是开发商的选择!”。
这确实不是一个始终有效的答案。

为什么?让我们看看下一个期望:
A Human可以吃,但显然Robot不能甚至不需要。

如果您使用抽象类实现行走功能会怎样?你最终会得到:

public abstract class Biped {  
  public void abstract walk();
} 

public Robot extends Biped {
   public void walk() {
     //walk at 10km/h speed
   }
}

public Human extends Biped {
   public void walk() {
     //walk at 5km/h speed
   }
}

你怎么能插上eating特征?你被困住了,因为你无法在Biped基类,因为它会破坏里氏替换原则,由于Robot不吃! 而你无法期望Human由于已知的 Java 规则,扩展了另一个基类。

当然,您可以添加专门用于人类的特定 Feedable 接口:

public interface Feedable {
  void eat();
} 

签名变为:public Human extends Biped implements Feedable {显然,拥有一个没有任何意义并且令人困惑role一个通过类实现,另一个通过接口实现。

这就是为什么只要我们有选择,从界面开始确实是首选。

通过接口,我们可以建模Roles轻松地通过作曲。

所以最终的解决方案是:

public interface Walkable {
   void abstract walk();
} 

public interface Feedable {
   void eat();
} 

public Robot implements Walkable {
   public void walk() {
     //walk at 10km/h speed
   }
}

public Human implements Walkable, Feedable {
   public void walk() {
     //walk at 5km/h speed
   }

   public void eat(){
     //...
   }    
}

难道它没有提醒你接口隔离原则? ;)

总而言之,如果您指定IS-A关系,使用抽象类。 如果您意识到您要建模Role(假设一个有能力关系),与接口一起走。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

抽象类与所有方法抽象和接口之间的区别? 的相关文章

随机推荐