接口和抽象类的区别


87.jpg

这是一个非常经典的Java基础题,再次整理出来,除了巩固之用外也是对一些新特性的总结(随着Java的不断发展,Jdk8 Jdk9的发布,接口和抽象类也发生了一些改变)。

根据“国际上”的标准回答(就业季看过面经的应该有过了解)

接口和抽象类是Java的两个基础机制。接口是对行为的抽象,他是抽象方法的集合。接口不用被实例化,不能包含非常量成员。所有成员默认被public static final所修饰,接口中也没有非静态方法的实现,所有方法要么是抽象方法,要么是静态方法。接口实现了定义与实现分离的目的。

抽象类也不能被实例化,但是形式上和一般的Java方法没有太大区别,一个抽象类中可以有一个或者多个抽象方法,也可以不含有抽象方法。抽象类是对共有方法实现或者共有的成员变量的抽取,主要用于代码重用(通过继承的方式)。

关于接口和抽象类需要注意的有以下几点:

Java不支持多继承,但是可以实现多个接口

继承是一种紧耦合关系,父类代码改变,子类行为也会变动。实际应用中,过多的使用继承可能会出现反效果。

在接口中添加抽象方法,相应的所有实现该接口的类,也必须实现新增的方法,否则就会报编译错误。抽象类则没有此限制,子类只会享受父类方法的扩展(用不用新的方法由子类做主),不用担心报编译错误。

Java中存在一种Marker Interface标记接口,没有任何方法,只用作声明使用。例如: Cloneable,Serializable

新特性:

从Java8开始,接口也是可以有实现方法的,接口增加了对 default method的支持。Java9之后增加了对private default method的支持。

也就是说在Java8中接口中了default方法和static方法都可以有方法体

下面通过一个例子我们来看一下具体的实现:

测试接口(包含default方法/static方法/一般方法):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package test;

public interface InterfaceTest {

default void defaultMethod() {
System.out.println("This is a default method!");

System.out.print("调用本接口中的static方法:");
InterfaceTest.staticMethod();
}

static void staticMethod() {
System.out.println("This is a static method!");
}

public void method();
}

接口实现类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package test;

public class InterfaceTestImpl implements InterfaceTest {

@Override
public void method() {
System.out.println("实现InterfaceTest接口中的method方法。");

this.defaultMethod();
}

public static void main(String[] args) {

InterfaceTestImpl interfaceTestImpl = new InterfaceTestImpl();

interfaceTestImpl.method();
}
}

Output:

1
2
3
实现InterfaceTest接口中的method方法。
This is a default method!
调用本接口中的static方法:This is a static method!

可以发现我们在接口实现类中实现接口中的方法是根本zh找不到接口中的static方法

Interface.png

结论:Java8 确实增强了接口,default方法和static方法中都可以由具体的实现,但是static方法不能被继承,也不能被实现类调用,只能被自身调用。default方法可以被子接口继承同时也可以被其实现类所调用