一. 概述
接口interface和抽象類abstract Class是支持抽象類定義的兩種機制。接口和抽象類都是不能夠被實例化的,同時繼承了抽象類的子類和實現了接口的實現類只有實現了接口和抽象類中的抽象方法纔可以被實例化。
抽象類:
1. 可以有私有方法和私有變量的,且成員變量都是default,可以在子類中重新定義,也可以被重新賦值。
2. 通過關鍵字abstract來聲明一個類爲抽象類,同時抽象類中的抽象方法沒有方法體。
3. 子類實現方法必須含有相同的或者更低的訪問權限(public > protected > private)。
4. 抽象類的子類必須實現父類中的所有抽象方法,否則子類也爲抽象類。
5. 抽象類中可同時有關鍵字abtract修飾的抽象方法(只能定義不能實現,抽象方法被abstract
修飾,不能被private
、static
、synchronized
和native
等修飾,必須以分號結尾,不帶花括號)和普通方法(既能定義又能實現)。
6. 抽象類必須用public、procted 修飾(如果爲private修飾,那麼子類則無法繼承,也就無法實現其抽象方法)。默認缺省爲 public。
接口:
1. 可以看作爲一種特殊的抽象類,接口是公開的,不能有私有的方法和變量,且變量默認隱式爲public static final,且必須賦初值,且不能被重新賦值,即不能被修改。
2. 通過關鍵字interface來聲明一個類爲接口,接口中的所有方法都是抽象方法且沒有方法體,抽象方法默認隱式都是public abstract 關鍵字修飾(並且只能是 public ,如果是 private,procted,那麼就編譯報錯),且不能是 static,接口中的方法也不允許子類覆寫,抽象類中允許有static 的方法。
3. Java是單繼承多實現的語言,即一個類可以實現多個接口,所以可以通過接口來間接實現多重繼承。
4. 接口中的只由被定義,而不能實現的抽象方法,Java1.8可以定義default方法體。
5. 接口中沒有 this
指針,沒有構造函數,不能擁有實例字段(實例變量)或實例方法。
二. 代碼示例
抽象類:
public abstract class Test{
//普通成員變量
private int age;
//靜態方法
abstract void method();
//普通成員方法
public string method() {
C
System.out.println("This is abstract class!");
}
}
Jdk8前的接口:
interface Test {
public static final int age = 18;
//方法隱式的是public abstract修飾
String getString(參數列表);
}
Jdk8後的接口允許我們在接口中定義static方法和default方法且可以使用default關鍵字實現默認的方法:
//jdk8及以後,允許我們在接口中定義static方法和default方法。
public interface JDK8Interface {
//static 修飾定義靜態方法
static void staticMethod(){
System.out.println("接口中的靜態方法。");
}
//default修飾符定義默認方法
default void defaultMethod() {
System.out.println("接口中的默認方法。");
}
}
總結:
- 抽象類和接口都不能直接實例化,如果要實例化,抽象類變量必須指向實現所有抽象方法的子類對象,接口變量必須指向實現所有接口方法的類對象。
- 抽象類要被子類繼承,接口要被類實現。
- 接口裏定義的變量只能是公共的靜態的常量,抽象類中的變量是普通變量。
- 抽象類裏可以沒有抽象方法。
- 接口可以被類多實現(被其他接口多繼承),抽象類只能被單繼承。
- 接口中沒有 this 指針,沒有構造函數,不能擁有實例字段(實例變量)或實例方法。
- 抽象類不能在Java 8 的 lambda 表達式中使用。
三. final關鍵字
final關鍵字可以修飾類,成員變量和方法中的局部變量。
1. final類
final類是不能被繼承的,即不能夠有子類。
2. final方法
如果用final修飾父類中的一個方法,那麼這個方法就不允許子類進行重寫,也就是說,不允許子類隱藏可以繼承的final方法(只能繼承,不能重寫)。
3. 常量
如果成員變量或者局部變量被修飾爲final,那麼它就是常量。由於常量在運行期間不允許修改,所以常量在聲明時是沒有默認值的,這就是要求我們在聲明變量時必須指定該變量的值。