标签:java oop interface abstract-class
我接受采访时,面试官首先问我抽象类与抽象方法和界面之间的区别.
我回答说,如果将来要求继承某些内容,如果你已经扩展了课程,那么你将无法继续.
然后,他说这是一种情况,人们永远不必延长任何其他阶级,你必须实施合同.在这种情况下,哪个更好,一个抽象类或接口?
我告诉他你可以使用其中任何一个,但他不满意.我无法理解为什么 – 我相信这是开发人员/设计选择.
解决方法:
说明接口代表合同的答案是不可接受的.
这就是我们给Junior的答案,因为它可能很复杂,可以清楚地弄清楚抽象类的本质与界面的本质之间的区别,而没有太多的架构经验,也没有阅读很多经典书籍.
任何具有公共方法的抽象类都充当契约,以及接口.
在99%的情况下,不提供任何实现的抽象类是对象角色的表示.
接口表示角色.
每个对象可能有几个不同的角色,这些角色不应该绑定在一起,而是由相关对象组成.
我用这个例子解释这个:
你的面试官可以说:
我有一个可以行走的机器人和一个可以行走的人类.
所以基于这种情况,他问你:我应该在抽象基类或界面中提取步行特征,知道实现没有任何共同之处吗?
你认为……“哦,我知道:在这种情况下,有一个带抽象方法walk()的抽象类,那么显然与使用walk()方法声明一个接口相同.”
所以你的答案肯定是:“这是开发人员的选择!”.
这真的不是一个永远有效的答案.
为什么?让我们看看下一个期望:
一个人可以吃,但显然机器人不能,甚至不需要.
如果您使用抽象类实现了行走功能,该怎么办?你会最终得到:
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
}
}
你怎么能插上吃的功能?你被困了,因为你不能在Biped基类中实现它,因为它会打破Liskov Substitution Principle,因为机器人不吃!
而且由于已知的Java规则,您不能指望Human扩展另一个基类.
当然,您可以添加仅专用于Human的特定Feedable界面:
public interface Feedable {
void eat();
}
签名变为:public Human extends Biped实现Feedable {
显然,通过一个接口实现一个角色和另一个角色是没有意义和困惑的.
这就是为什么每当我们有选择时,首先选择接口是首选.
通过界面,我们可以通过编写轻松地为角色建模.
那么最终的解决方案是:
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(){
//...
}
}
它不提醒您接口隔离原则吗?
标签:java,oop,interface,abstract-class 来源: https://codeday.me/bug/20190517/1119905.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。