抽象类和接口在所有面向对象的编程语言中都非常流行。几乎在每次 Java 面试中,您都至少会遇到一个与此主题相关的问题。由于接口在软件设计人员中很受欢迎,因此被更频繁地提及,但关于抽象类的问题也时常出现。后者最常被问及初级开发人员职位的申请人,例如,Java 开发经验不超过两年的申请人,而在面试那些经验已经超过四年的人时,最常遇到有关接口的问题。它们通常与有关 Java 设计模式的其他问题一起提出,例如装饰器或工厂模式。
在本文中,我们将讨论在各个级别的 Java 面试中提出的有关抽象类和接口的常见问题。即使对于新手 Java 程序员来说,其中大多数也不应该困难。这些大多是纯粹的知识问题,但其中一些问题,例如
Java 中抽象类和接口之间的区别,或者何时
选择抽象类而不是接口,可能相当棘手。我们为您提供了有关该主题的十几个有趣的问题。
如果您曾经在面试中被问到一个问题,或者不得不问任何有关抽象类和接口的有价值的问题,但它不在此列表中,请在评论中分享。 |
1. Java中抽象类可以有构造函数吗?
是的,在 Java 的抽象类中,您可以声明和定义构造函数。由于不可能创建抽象类的实例,因此只有在形成构造函数链时,即创建具体实现类的实例时,才能调用这样的构造函数。但想象一下,面试官随后问了一个问题:如果无论如何都无法创建抽象类的实例,那么构造函数的意义何在?重点是它仍然可以用来设置在抽象类中声明并由各种实现使用的公共变量的初始值。即使您没有声明任何构造函数,编译器也会向抽象类添加默认的无参构造函数。如果没有它,您的子类将无法编译,因为任何构造函数中的第一个语句都是
super()
对 Java 中默认超类构造函数的隐式调用。
2、Java中的抽象类可以实现接口吗?他们必须实施所有方法吗?
是的,抽象类可以使用
implements
. 由于它们是抽象的,因此不需要它们实现所有方法。推荐的做法是使用抽象基类和接口来声明类型。一个例子是接口
java.util.List
和相应的抽象类
java.util.AbstractList
。因为
AbstractList
它实现了所有通用方法,所以特定实现(例如
LinkedList
和
ArrayList
)不必实现所有方法,就像
List
直接实现接口的情况一样。该解决方案结合了使用接口声明类型的优点和抽象类的灵活性,可以在一个地方实现所有常见行为。在 Joshua Bloch 的书
《Java. 《高效编程》中有一个关于在 Java 中使用接口和抽象类的主题的精彩章节,为了更好地理解,研究它是有意义的。
3.抽象类可以是final的吗?
不他不能。该关键字
final
意味着该类位于层次结构的顶部,并且不能有后代。没有继承人的抽象类就像真空中的球形马,因为它不可能创建实例
abstract class
。因此,如果一个类既是 又是
abstract
和
final
,那么它没有后代并且不能被实例化。如果你创建一个类
abstract
并且
final
.
4. Java中的抽象类可以有静态方法吗?
是的,抽象类可以声明和定义静态方法。只需要遵循在 Java 中创建静态方法的一般原则,因为它们在面向对象的设计中是不可取的,因为在 Java 中重写静态方法是不可能的。抽象类中的静态方法非常罕见,但如果有充分的理由,没有什么可以阻止您使用它们。
5. 是否可以实例化抽象类?
不,你不能这样做。抽象类的本质是它不完整,需要在其后代类中完成。也就是说,这个类还没有准备好使用。例如,它可能缺少某些方法的实现。由于类尚未准备好使用,因此无法创建其对象。但是您可以创建抽象类的继承者的实例。如果程序尝试实例化抽象类,Java 编译器将抛出错误。
6、抽象类必须有抽象方法吗?
不,抽象类不能有任何抽象方法。
abstract
在 Java 中,只需在声明中使用关键字即可将类抽象化。编译器将强制执行任何结构限制,例如不允许创建此类的实例化。顺便说一句,抽象类或接口中是否应该有抽象方法的问题是有争议的。在我看来,抽象类应该有抽象方法,因为这是程序员看到抽象类时首先想到的。这非常符合尽量减少意外的原则。
7. Java中抽象类和接口有什么区别?
这是最重要也是最经典的Java面试题之一。我已经数不清在各个级别的Java面试中见过多少次这个问题了。这个问题之所以有趣,特别是因为申请人有机会提供一个例子。回答有关面向对象编程基础知识的问题,例如抽象、封装、多态性和继承,很容易,但当涉及到这些微妙的细微差别时,求职者常常会感到困惑,并说出首先想到的事情。
这个问题的答案值得单独写一篇文章(特别是在 Java 8 发生变化之后),但简而言之:
- 接口仅描述对象的行为(方法),但它没有状态(字段)(除了
public static final
),而抽象类可以拥有它们。
- 抽象类是继承(扩展)的,接口是实现(实现)的。我们可以只继承一个类,但可以实现任意多个接口。一个接口可以扩展(扩展)另一个接口。
- 当存在“is-a”关系时使用抽象类,即子类扩展基抽象类,并且接口可以由彼此完全不相关的不同类实现。
8. 什么时候更喜欢抽象类而不是接口,反之亦然?
这是之前关于抽象类和接口的问题的延续。如果您知道它们的语法差异是什么,那么回答这个问题不会给您带来问题,因为它们是做出决定的决定性因素。由于几乎不可能向已发布的接口添加新方法,因此最好使用抽象类,以防可能需要进一步开发。在 Java 中开发抽象类比开发接口更容易。同样,如果一个接口有太多方法并且实现它们都变得非常令人头疼,那么最好为默认实现创建一个抽象类。Java 集合包中遵循这种模式,抽象类
AbstractList
提供了
List
.
在以下情况下使用抽象类:
- 您希望在几个密切相关的类之间共享代码。
- 您可能期望扩展抽象类的类具有许多共同的方法或字段,或者需要除
public
(例如,protected
和private
)之外的访问修饰符。
- 您想要声明非静态或
не-final
字段。这允许您定义可以访问和更改其所属对象的状态的方法。
在以下情况下使用接口:
- 您期望不相关的类实现您的接口。例如,接口
Comparable
和Cloneable
是由许多不相关的类实现的。
- 您想要定义特定数据类型的行为,但您不关心由谁实现它。
- 您想要使用多类型继承。
9. Java中什么是抽象方法?
抽象方法是没有主体的方法。
abstract
您只需在方法声明中使用关键字来声明方法而不定义它。默认情况下,Java 语言中接口内声明的所有方法都是抽象的。下面是 Java 中抽象方法的示例:
public void abstract printVersion();
现在,要实现此方法,您需要扩展抽象类并重写此方法。
10. Java中的抽象类可以包含方法吗main
?
是的,Java中的抽象类可以包含方法
main
,因为它只是另一个静态方法,并且抽象类可以使用方法来执行
main
,只要你不实例化它。这就是我想告诉你的。请记住:抽象类和接口是面向对象分析和设计过程中的关键设计决策,当然,如果您想创建灵活的系统,则应谨慎使用。
GO TO FULL VERSION