抽象类和接口的区别已经变了
2015 年 11 月 27 日
随着JDK的不断迭代,抽象类和接口的区别已经有了些许改变,你是否还停留在JDK 7 的答案呢?
定义
-
抽象类定义通过 abstract class
public abstract class A {}
-
接口定义通过 abstract(默认) interface
public abstract interface A {}
派生方式
-
子类继承抽象类通过 extends , 单继承
public abstract class A {} public class B extends A {}
-
抽象类实现接口通过 implements , 多实现,接口继承接口通过 extends
public interface A {} public interface B {} public interface C extends A {} public class D implements B,C {}
-
子类(非抽象类)必须实现 抽象父类或接口 的全部未实现方法
实例化
-
抽象类和接口均不能实例化
-
抽象类可以有构造方法,接口不能有构造方法
public abstract class A { public A () {} }
属性
-
接口中定义属性只能是 (public)静态常量
public interface A { //默认(public static final) String A="ABC"; String A = "ABC"; }
-
抽象类中可以定义有任意变量常量
//任意访问修饰符的变量及常量 public abstract class A { private String a = "a"; boolean b = true; public char c = 'a'; protected int d = 2; public static final int e = 1; }
方法
抽象类
抽象类中可以和普通类中一样拥有各自普通方法,也可以拥有(不必须)抽象方法。
-
抽象方法没有方法体
-
抽象方法权限修饰符不能为 pirvate
public abstract class A { // protected or default public abstract void a(); }
抽象方法的目的就是为了让子类继承重写的,所以抽象方法不能私有,不能final修饰。
接口
JDK 7
-
只能有方法的声明
-
方法必须声明为 public (默认)
public interface A { //默认(public abstract) void test(); void test(); }
JDK 8
-
增加默认实现方法
public interface A { // 这里的 default 不能省略 public(默认自动添加) default void defaultMethod(){ //do something } }
默认方法的出现主要是面向类库的开发者的,在堆接口进行扩展时,大量的实现类会让人望而却步。 拥有默认方法后,子类可直接继承使用或重写。 另外,添加默认方法不会影响函数式接口的使用。
-
增加静态方法
public interface A { // 静态方法 public(默认自动添加) static void staticMethod(){ //do something } }
静态方法的调用直接通过接口名调用 A.staticMethod()
,子类无法重写(override), 但可以有同名方法。
JDK 9
-
增加私有方法
public interface A { // 不能被子类继承或重写 private void privateMethod(){ //do something } }
-
增加私有静态方法
public interface A { // 不能被子类继承或重写 private static void privateStaticMethod(){ //do something } }
这两种私有方法其实是对JDK8 默认方法和静态方法 的补充,这样可以避免代码的冗余。
设计
1. 抽象类是对一组类的共同特征进行抽象 ,是子类的模板(is-a)
2. 接口是对行为的抽象,是一种行为的规范和约束 (like-a)