本文参考自:Java中抽象类和接口的区别 https://blog.csdn.net/qq_41701956/article/details/86771426,文章中对于抽象类、接口在语法层面、设计层面上的区别讲解比较全面、通俗易懂。
不过,文章中并没有考虑到 jdk1.8 在interface中引入了static方法(包括main方法)、default方法。
结合该文章,本文进行简要的总结:
抽象类:
1. 抽象类不一定必须含有abstract抽象方法,即abstract 抽象方法可有可无。
2. abstract抽象方法必须用abstract关键字进行修饰,必须为public或者protected(如果为private,则不能被子类继承,子类便无法实现该方法),缺省情况下默认为public。
3. 抽象类不能被实例化---抽象类中可能含有无具体实现的方法,如果被实例化后调用该方法时则会报错。
4. 除去abstract方法,抽象类跟普通类几乎没有区别,比如属性/方法/构造器 的定义、使用,以及static代码块的存在。
1 public abstract class AbstractClassStudy { 2 String testStr; 3 4 static String str; 5 6 final String SSS = "f"; 7 8 private String ss; 9 10 public AbstractClassStudy() { 11 } 12 13 public AbstractClassStudy(String testStr, String ss) { 14 this.testStr = testStr; 15 this.ss = ss; 16 } 17 18 19 // 缺省情况下默认为public 20 abstract void testAbs(); 21 22 protected abstract void testAbssss(); 23 24 // abstract方法不能用private 修饰 25 // private abstract void testAbs(); 26 27 28 static{ 29 System.out.println("静态代码块"); 30 } 31 32 static void staticMethod(){ 33 System.out.println("This is staticMethod..."); 34 }; 35 36 final void finalMethod() { 37 System.out.println("final 方法"); 38 } 39 40 private void privateMethod(){ 41 str = "jj"; 42 System.out.println("final String sss = " + SSS); 43 }; 44 }
5. 如果一个子类继承于一个抽象类,则子类必须实现父类的抽象方法。否则必须将子类也定义为为abstract类。
接口:
1. 接口中一般不定义变量。如果定义,则会被隐式地指定为public static final, 并且只能是public static final,而且由于是final类型所以必须赋予初值.
2. (除了jdk1.8引入的public 的static方法、default 方法)接口中的方法会被隐式地指定为public abstract方法, 并且只能是public abstract。
1 public interface InterfaceStudy { 2 /** 3 * 一般情况下,不在接口中定义变量 4 */ 5 String TEST_STR = null; 6 7 static String STA_STR = ""; 8 9 final String SS = null; 10 11 /** 12 * 接口里定义的属性只能是public、且static 的final常量 13 */ 14 //private String str = null; 15 16 //protected String s = null; 17 18 19 void myPrint(); 20 21 // 接口中不能含有静态代码块 22 // static{ } 23 24 // static方法必须是public类型的 25 static void myPrintStatic() { 26 // 接口里定义的属性只能是public、且static 的final 常量 27 // TEST_STR = ""; 28 System.out.println("This is myPrintStatic... "); 29 } 30 31 // 接口方法默认是abstract的,所以不能用final修饰 32 // final void myPrintFinal(); 33 34 /** 35 * 接口中的方法会被隐式地指定为public abstract方法且只能是public abstract 36 */ 37 // private void myPrivate(); 38 // protected void dfdf(); 39 }
3. 接口中不能含有静态代码块。 jdk1.8 在interface中引入了public的static方法、default方法。
4. 如果一个非抽象类实现了某个接口,就必须实现该接口中的所有方法。对于实现某个接口的抽象类,可以不实现该接口中的抽象方法。
抽象类、接口的主要区别:
1. 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型的;
2. 抽象类可以有多种类型的方法形式(抽象方法、普通方法、私有方法、构造器等等),并提供成员方法的实现细节,而接口中一般不能有方法的实现、不能有构造器,只能存在public abstract 方法,以及jdk1.8引入的static方法、default方法;
3. 抽象类可以有静态代码块、静态方法,而接口中不能含有静态代码块(jdk1.8 可以有static方法、default方法);
4. 一个类只能继承一个抽象类,而一个类却可以实现多个接口。
采用表格的形式来总结:
项目 | 抽象类 | 接口 |
属性、成员变量 | 与普通类的属性无区别(比如可以被public、private、default、protected、static、final等等修饰) | 只能是public static final 类型的,而且由于是final类型所以必须赋初值 |
默认的方法实现 | 可以有默认的方法实现 |
接口方法一般是抽象的,一般不存在方法的实现。 (jdk1.8)可以通过public的static方法、default方法提供实现。 |
访问修饰符 | 抽象方法可以用public、protected修饰;非抽象方法与普通类的方法无区别 | 抽象方法是public abstract类型,(jdk1.8)static方法、default方法是public类型。 |
main方法 | 可以有main方法并且可以运行 | (jdk1.8)可以有main方法并且可以运行 |
构造器 | 抽象类可以有构造器 | 接口不能有构造器 |
与正常Java类/接口的区别 | 除了abstract方法、以及不能实例化抽象类之外,和普通Java类没有任何区别 | 接口是完全不同的类型 |
实现 | 子类使用extends关键字来继承抽象类。如果子类不是抽象类的话,它需要提供抽象类中所有声明的方法的实现。 | 子类使用关键字implements来实现接口。如果子类不是抽象类的话,它需要提供接口中所有声明的方法的实现 |
多继承 | 子类只可以继承一个类,或实现多个接口 | 子类可以实现多个接口,子接口可以继承多个接口 |
速度 | 比接口速度要快 | 接口是稍微有点慢的,因为它需要时间去寻找在类中实现的方法。 |
添加新方法 | 如果往抽象类中添加新的方法,你可以给它提供默认的实现。因此可以不需要改变现有的代码。 | 如果往接口中添加方法,一般情况下你必须改变所有实现该接口的类(子类为抽象类除外) |
原文:https://www.cnblogs.com/kekeCnblogs/p/14774739.html