在Java中什么时候应该选择抽象类而不是接口?接受挑战吧!了解这些Java语言元素之间的区别以及如何在你的程序中使用它们。
在Java代码中,甚至在Java开发工具包(JDK)本身中,都有大量的抽象类和接口。每个代码元素都有一个基本的目的:
- 接口 是一种 代码契约 ,必须由一个具体的类来实现。
- 抽象类 与普通类相似,不同的是它们可以包括 抽象方法 ,也就是没有主体的方法。抽象类不能被实例化。
许多开发者认为接口和抽象类是相似的,但它们实际上是完全不同的。让我们来探讨一下它们之间的主要区别。
接口的本质
从本质上讲,接口是一个契约,所以它依赖于一个实现来达到其目的。一个接口 永远不可能有状态 ,所以它不能使用可变的实例变量。一个接口只能使用最终变量。
何时使用接口
接口对于解耦代码和实现多态性非常有用。我们可以在JDK中看到一个例子,就是 List
接口:
public interface List<E> extends Collection<E> {
int size();
boolean isEmpty();
boolean add(E e);
E remove(int index);
void clear();
}
正如你可能注意到的,这段代码很短,而且描述性很强。我们可以很容易地看到 方法的签名 ,我们将用一个具体的类来实现接口中的方法。
List
接口包含一个契约,可以由 ArrayList
, Vector
, LinkedList
, 和其他类来实现。
为了使用多态性,我们可以简单地用 List
来声明我们的变量类型,然后选择任何一个可用的实例化。这里有一个例子:
List list = new ArrayList();
System.out.println(list.getClass());
List list = new LinkedList();
System.out.println(list.getClass());
下面是这段代码的输出:
class java.util.ArrayList
class java.util.LinkedList
在这种情况下, ArrayList
, LinkedList
, 和 Vector
的实现方法都是不同的,这就是使用接口的一个很好的场景。如果你注意到许多类都属于一个父类,其方法动作相同,但行为不同,那么使用接口是个好主意。
接下来,让我们来看看我们可以用接口做的几件事。
重写一个接口方法
记住,接口是一种必须由具体类来实现的契约。接口方法是隐含的抽象的,也需要一个具体类的实现。
这里有一个例子:
public class OverridingDemo {
pu