在一次采访中,我被要求解释接口和抽象类之间的区别。
以下是我的回答。
Java接口的方法是隐含的抽象的,不能有实现。 而不能有实现。一个Java抽象类可以有 实例方法,实现默认行为。
在一个Java接口中声明的变量默认为最终变量。一个 抽象类可以包含非最终变量。
一个Java接口的成员默认为公共的。一个Java抽象 类可以有通常意义上的类成员,如私有的。 保护等等。
一个Java接口应使用关键字 "实现 "来实现;一个 Java抽象类应使用关键字 "extends "来扩展。
一个接口只能扩展另一个Java接口,一个抽象类可以扩展另一个Java类并实现多个Java接口。 可以扩展另一个Java类并实现多个Java接口。
一个Java类可以实现多个接口,但它只能扩展 一个抽象类。
然而,面试官并不满意,他告诉我,这种描述代表了"书本上的知识"。
他要求我做出更实际的回答,用实际例子解释什么时候我会选择一个抽象类而不是一个接口。
我哪里做错了?
在这个世界上没有什么是完美的。他们可能期待的是更多的实用方法。
但是在你的解释之后,你可以用稍微不同的方法加上这些句子。
1.接口是规则(规则是因为你必须给它们一个实现,你不能忽视或避免,所以它们就像规则一样被强加于人),它作为软件开发中各个团队之间的共同理解文件发挥作用。
2.2.接口给出了要做什么的想法,但没有给出如何做。因此,实现完全取决于开发者是否遵循给定的规则(指给定的方法签名)。
3.3.抽象类可以包含抽象声明、具体实现,或者两者都包含。
4.4.抽象声明就像需要遵循的规则,而具体实现就像指南(你可以按原样使用它,也可以通过重写并给它提供你自己的实现而忽略它)。
5.5.此外,具有相同签名的方法在不同的环境下可能会改变行为,这些方法作为接口声明被提供,作为在不同环境下相应实现的规则。
编辑: Java 8为在接口中定义默认和静态方法提供了便利。
public interface SomeInterfaceOne {
void usualAbstractMethod(String inputString);
default void defaultMethod(String inputString){
System.out.println("Inside SomeInterfaceOne defaultMethod::"+inputString);
}
}
现在,当一个类要实现SomeInterface时,不一定要为接口的默认方法提供实现。
如果我们有另一个具有以下方法的接口。
public interface SomeInterfaceTwo {
void usualAbstractMethod(String inputString);
default void defaultMethod(String inputString){
System.out.println("Inside SomeInterfaceTwo defaultMethod::"+inputString);
}
}
Java不允许扩展多个类,因为这会导致"钻石问题 ",即编译器无法决定使用哪个超类方法。有了默认方法,钻石问题也会出现在接口上。因为如果一个类同时实现了
SomeInterfaceOne and SomeInterfaceTwo
而没有实现共同的缺省方法,编译器就无法决定选择哪一个。 为了避免这个问题,在java 8中,必须实现不同接口的共同默认方法。如果任何一个类同时实现了上述两个接口,它就必须为defaultMethod()方法提供实现,否则编译器将抛出编译时错误。
你的解释看起来很得体,但可能是你看起来像从教科书上读出来的?
我更关心的是,你的例子有多牢固?你是否费力地包括了抽象和接口之间的几乎所有区别?
我个人会建议使用这个链接。 http://mindprod.com/jgloss/interfacevsabstract.html#TABLE
以获得一份详尽的差异清单。
希望这对你和所有其他读者在未来的采访中有所帮助
接口是一个"契约",实现该契约的类承诺要实现这些方法。我不得不写一个接口而不是一个类的例子是,我在把一个游戏从2D升级到3D时。我必须创建一个接口,在游戏的2D和3D版本之间共享类。
package adventure;
import java.awt.*;
public interface Playable {
public void playSound(String s);
public Image loadPicture(String s);
}
然后我可以根据环境来实现方法,同时还能从一个不知道正在加载哪个版本游戏的对象中调用这些方法。
public class Adventure extends JFrame implements Playable
。
公用类Dungeon3D扩展SimpleApplication实现Playable`。
公有类Main扩展SimpleApplication实现AnimEventListener, ActionListener, Playable`。
通常,在游戏世界中,世界可以是一个抽象的类,对游戏执行方法。
public abstract class World...
public Playable owner;
public Playable getOwner() {
return owner;
}
public void setOwner(Playable owner) {
this.owner = owner;
}