abstract修飾符
abstract修飾符可用來修飾類和實例成員方法
用abstract修飾的類表示抽象類,抽象類不能被實例化。沒有用abstract修飾的類稱爲具體類,具體類可以被實例化。
用abstract修飾的方法表示抽象方法,抽象方法沒有方法體。抽象方法用來描述系統具有什麼功能,但不提供具體的實現。沒有用abstract修飾的方法稱爲具體方法,具體方法必須要有方法體。
使用abstract修飾符需要遵守以下語法規則:
(1)抽象類中可以沒有抽象方法,但包含了抽象方法的類必須被定義爲抽象類。如果子類沒有實現父類中所有的抽象方法,那麼子類也必須被定義爲抽象類,否則編譯出錯。
(2)沒有抽象構造方法,也沒有抽象靜態方法。
abstract class Base {
abstract Base() {} //編譯出錯,構造方法不能是抽象的
static abstract void method1(); //編譯出錯,static和abstract修飾符不能連用
static void method2() {...} //合法,抽象類中可以有靜態方法
}
(3)抽象類中可以有非抽象的構造方法,創建子類的實例時可能會調用這些構造方法。抽象類不能被實例化,然而可以創建一個引用變量,其類型是一個抽象類,並讓它引用非抽象的子類的一個實例。
(4)抽象類及抽象方法不能被final修飾符修飾。即,abstract與final不能連用。這是因爲abstract與final的作用是恰恰相反的,如:抽象類只允許創建其子類,而final修飾的類不允許擁有子類; 抽象方法必須被子類的具體方法來實現,而final修飾的方法不允許被子類方法覆蓋。
爲什麼抽象類不允許被實例化?
在語義上,抽象類表示從一些具體類中抽象出來的類型。從具體類到抽象類,這是一種更高層次的抽象。如:蘋果類、香蕉類和桔子類是具體類,而水果類則是抽象類,在自然界並不存在水果類本身的實例,而只存在它的具體子類的實例。
Fruit fruit = new Apple(); //創建一個蘋果對象,把它看做是水果對象
在語法上,抽象類中可以包含抽象方法,如果抽象類可以實例化,那麼在訪問抽象方法時將無法執行,因爲抽象方法中根本就沒有方法體。由此可見,Java編譯器不允許創建抽象類的實例是必要的。
abstract class Base {
public void method1() {...} //具體方法
public abstract void method2(); //抽象方法
}
Base base = new Base(); //假定Java編譯器沒有報錯
base.method1();
base.method1(); //運行時Java虛擬機無法執行這個方法