我們來舉個例子,然後引出這個問題的答案:
市面上有 噴墨式打印機 和 針式打印機 這兩種形式的打印機,我們需要編程來實現他們的 開機,關機以及打印。
構建父類Printer
class Printer
{
void open(){
System.out.println("OPEN");
}
void close(){
System.out.println("CLOSE");
}
void print(){ //由於兩種打印機的打印方式不同,所以無法在父類裡面寫出具體打印方式,因此空著。
}
}
構建子類HPprinter
//該打印機為噴墨打印機
class HPprinter extends Printer
{
void print(){
System.out.println("噴墨打印");
}
}
構建子類Canonprinter
//該打印機為針式打印機
class Canonprinter extends Printer
{
void print(){
System.out.println("針式打印");
}
}
構建主函數 Test 實現功能
class Test
{
public static void main(String args[]){
Printer HP = new HPprinter();
HP.open();
HP.print();
HP.close();
Printer Canon = new Canonprinter();
Canon.open();
Canon.print();
Canon.close();
}
}
編譯運行發現沒有錯誤。
可是,計算機說沒有錯誤就真的沒有錯誤嗎?不見得。設想一下,如果,寫子類程序的人要是粗心,忘記了復寫父類的 void print(){}; 會發生什麼事情?
當然,編譯時沒有錯誤的,可是,打印機卻沒有了最重要的功能,並且,這種情況電腦是不會告訴你,哪兒有問題的。雖然這是個可能性很低的例子,但是大家不要糾結於此,且看老夫引蛇出洞:
既然問題出現了,那就有解決方法,這時,我們靈光乍現,忽然想起了親愛的 抽象函數,它不就是干這個的嗎?
重新定義父類 Printer
abstract class Printer
{
void open(){
System.out.println("OPEN");
}
void close(){
System.out.println("CLOSE");
}
abstract void print(){
}
}
現在當我們忘記復寫 print(){}; 的時候,系統是編譯不過去的,重新實現人機結合。同時,需要注意的一句話是:
如果一段代碼在語意上是錯誤的,那它在語法上也應該是有錯誤的,比如說我們之前的 print(){}; ,它居然是空著的,那它就是在語意上說不過去,所以語法上也是有錯誤的,只不過編譯器沒有識破它。最後我們還是用抽象函數這個語法解決了問題。