1. 为什么还要使用抽象类

在某些情况下,即使存在接口,仍然可能使用抽象类:

  • 代码重用: 抽象类可以包含实例变量和具体方法的实现,这使得代码重用更加方便。如果多个类有相似的实现,抽象类可以提供这些实现,减少冗余代码。值得一提的是:Java 8 之后,接口也可以有 default 方法来提供默认的方法实现了。

  • 构造方法: 抽象类可以拥有构造方法,而接口不能。这对于在对象创建时进行一些初始化工作是非常有用的。

  • 设计层次结构: 当我们需要建立一种层次结构,其中某些类具有通用的实现,而其他类则根据需要进行扩展时,抽象类提供了更灵活的选择。

2. 抽象类和接口在实际使用中的区别

  • 多重继承: 接口支持多重继承,一个类可以实现多个接口,而抽象类只支持单一继承。

  • 构造方法: 抽象类可以有构造方法,而接口不能。抽象类的构造方法在子类实例化时被调用,可以进行一些初始化操作。

  • 默认方法和静态方法: Java 8 之后,接口引入了默认方法和静态方法,使得接口更具灵活性。抽象类在Java 8 之前没有这些概念。

3. 两者在 Java 8 发布前后的区别

在Java 8之前和之后,接口和抽象类之间的一些区别:

  • 默认方法和静态方法: Java 8 引入了接口中的默认方法和静态方法,使得接口可以包含具有默认实现的方法。抽象类在Java 8之前没有这些概念,所以接口变得更加灵活。

  • 多重继承问题: 在 Java 8 之前,接口的多重继承问题是一个挑战,而 Java 8 引入的默认方法在一定程度上解决了这个问题。

  • 实例变量: 接口中的成员变量默认是 public static final` 的,而抽象类可以包含实例变量,并且可以使用各种修饰符。