目錄
1.抽象類/方法
1.1 基本介紹
1.2 語法格式
1.3 使用細節
2. 模板設計模式(抽象類使用場景)
2.1 基本介紹
2.2 具體例子
1.抽象類/方法
1.1 基本介紹
①?當父類的某些方法,需要聲明,但是又不確定如何實現時,可以將其聲明為抽象方法
②?類中只要存在一個抽象方法,則該類必須為抽象類
③?抽象類的價值更多作用在于設計,具體來說:設計者設計好后,讓子類繼承并實現父類的抽象方法
public class Test {public static void main(String[] args) {Dog dog = new Dog();dog.eat();}
}//抽象類
abstract class Animal{//抽象方法,只知道吃的動作,但不知道具體的動物吃什么東西public abstract void eat();
}class Dog extends Animal{public void eat(){System.out.println("狗吃骨頭");}
}
1.2 語法格式
-
抽象類:被 abstract 修飾的類,一般會被繼承,由其子類來實現抽象的方法
[修飾符] abstract class 類名{}
-
抽象方法:被 abstract 修飾而且沒有方法體的方法,也叫做沒有實現的方法
[修飾符] abstract 返回值類型 方法名([形參列表]);//不需要方法體{}
1.3 使用細節
①?abstract 只能修飾類和方法,不能用來修飾屬性和其他的
②?使用 abstract?修飾類,只是表示該類為抽象類,類內部的屬性和方法不會自動具有 abstract?修飾符
③?抽象類不能創建對象實例
④?抽象類的本質還是類,可以有類的各種成員。比如:非抽象方法、構造器、非靜態方法/屬性、靜態方法/屬性等等,都可以繼承給子類
public class Test {public static void main(String[] args) {Dog dog = new Dog();System.out.println(Dog.num);System.out.println(dog.name);dog.eat();}
}//抽象類
abstract class Animal{public static int num = 1;public String name = "小馬";public abstract void eat();//抽象方法
}class Dog extends Animal{//實現父類的抽象方法public void eat(){System.out.println("狗吃骨頭");}
}
/*輸出結果
1
小馬
狗吃骨頭*/
⑤?如果一個類繼承了抽象類,則它必須實現抽象類的所有抽象方法,除非它自己也聲明為 abstract類,否則編譯不通過
?⑥?抽象方法不能使用 private、final、static 來修飾,因為這些關鍵字都是和重寫相違背的
????????private:如果父類的抽象方法用 private 修飾,那其子類沒有訪問權限,無法實現抽象方法
????????final:如果父類的抽象方法用 final 修飾,則該方法不能重寫,其子類無法實現抽象方法
? ? ? ? static:static 修飾的方法可以 "直接類.方法名" 調用,而 abstract 修飾的方法沒有方法體,因此兩者是相悖的【這樣理解不知道對不對】
2. 模板設計模式(抽象類使用場景)
2.1 基本介紹
抽象類體現的就是一種模板模式的設計,抽象類作為多個子類的通用模板,子類在抽象類的基礎上進行擴展、改造,但子類總體上會保留抽象類的行為方式
解決的問題:
①?當功能內部一部分實現是確定的,另一部分實現是不確定的,這時可以把不確定的部分暴露出去,讓子類去實現
②?換句話說,在軟件開發中實現一個算法時,整體步驟很固定、通用,這些步驟已經在父類中寫好了。但是某些部分易變,則易變部分可以抽象出來,供不同子類實現。這就是一種模板模式
看上面的文字可能會覺得很抽象,可以結合具體的例子理解一下
2.2 具體例子
需求:計算不同類各自任務的執行時間
未使用模板設計模式之前
public class demo {public static void main(String[] args) {new JobA().job();new JobB().job();}
}class JobA{public void job(){int result = 0;long startTime = System.currentTimeMillis();//開始時間for(int i=0;i<100000;i++){result += i;}long endTime = System.currentTimeMillis();//結束時間long duration = endTime - startTime;System.out.println("任務執行時間: " + duration + "毫秒");}
}class JobB{public void job(){int result = 1;long startTime = System.currentTimeMillis();//開始時間for(int i=0;i<8000;i++){result *= i;}long endTime = System.currentTimeMillis();//結束時間long duration = endTime - startTime;System.out.println("任務執行時間: " + duration + "毫秒");}
}
缺點:代碼冗余,復用性差,可以看到代碼整體的步驟是很固定的,如下:
①? 記錄任務開始時間
②? 執行任務
③? 記錄任務結束時間
④? 打印任務執行時間
其中,① ③ ④?是固定不變的,變的只有?②?,這就有了改進的空間
引入模板設計模式
優點:利用抽象類+動態綁定機制使得模板類中的 job() 可以動態調用執行方法,代碼復用性高 ?
public class demo {public static void main(String[] args) {new JobA().calculateJobTime();new JobB().calculateJobTime();}
}//模板類
abstract class Template{public abstract void job();//抽象方法//計算任務執行時間public void calculateJobTime(){long startTime = System.currentTimeMillis();//開始時間job();//動態綁定機制long endTime = System.currentTimeMillis();//結束時間long duration = endTime - startTime;System.out.println("任務執行時間: " + duration + "毫秒");}
}class JobA extends Template{//重寫抽象方法public void job(){int result = 0;for(int i=0;i<100000;i++){result += i;}}
}class JobB extends Template{//重寫抽象方法public void job(){int result = 1;for(int i=0;i<8000;i++){result *= i;}}
}