抽象方法和抽象類(abstract)
- 抽象方法和抽象類使用 abstract 來定義,有抽象方法的類必須被定義為抽象類,抽象類里可以沒有抽象方法;
- 抽象方法:只有方法簽名,沒有方法體的方法;
- 抽象類不能被實例化,也就是不能通過new關鍵字去產(chǎn)生對象,只能被繼承,但是可以定義變量,任何繼承了抽象類的非抽象類的對象可以給這個變量賦值;
- 抽象類的子類必須實現(xiàn)抽象類里的所有抽象方法,否則這個子類還是抽象類;
- 抽象類可以包含成員變量、方法(普通方法和抽象方法)、構(gòu)造器(并不用于創(chuàng)建對象,而是讓子類調(diào)用,從而完成屬于抽象類的初始化操作)、初始化塊、內(nèi)部類(接口、枚舉)。
抽象類的作用
抽象類是從多個具有相同特征的具體類中抽象出來的父類,以這個父類作為子類的模板,可以避免子類設計的隨意性。
模板方法模式(Template Method)
1. 模板方法模式是由抽象父類控制頂級邏輯,并把某些操作的實現(xiàn)推遲到子類去實現(xiàn)。
2. 如果編寫一個抽象父類,父類將部分邏輯以具體方法以及具體構(gòu)造函數(shù)的形式實現(xiàn),并把不能實現(xiàn)的部分抽成抽象方法,留給其子類去實現(xiàn),不同的子類可以以不同的方式實現(xiàn)這些抽象方法,從而對剩余的邏輯有不同的實現(xiàn),這種模式就叫模板方法模式。
具體例子:

上面定義了一個抽象的SpeedMeter類,用來計算車速。該類定義了兩個子類通用的方法——設置轉(zhuǎn)速的方法setTurnRate()和計算車速的方法getSpeed(),getSpeed()方法需要知道車輪的半徑,但SpeedMeter并不知道車輪的半徑,所以將其抽象成抽象方法,交由子類來實現(xiàn)。


上面定義了CarSpeedMeter類和BicycleSpeedMeter類,它們均繼承自SpeedMeter類,并實現(xiàn)了其父類中的抽象方法getRadius(),其中CarSpeedMeter類的半徑是0.31m,BicycleSpeedMeter類的半徑是0.33m。

上面定義了一個測試類,分別創(chuàng)建了CarSpeedMeter類和BicycleSpeedMeter類的對象,并分別設置它們的轉(zhuǎn)速,最后打印它們各自的車速。
運行結(jié)果:

模板方法模式(Template Method)的應用場景
- 具有統(tǒng)一的操作步驟或操作過程
- 具有不同的操作細節(jié)
- 存在多個具有同樣操作步驟的應用場景,但某些具體的操作細節(jié)卻各不相同
接口(interface)
- 接口里可以包含成員變量、方法、內(nèi)部類(包括內(nèi)部接口和枚舉),不能有構(gòu)造器和初始化塊;
- 接口里的成員變量必須初始化(即必須賦初值),且均為靜態(tài)常量(即此值一旦賦值便不能再更改,系統(tǒng)會自動為成員變量添加static和final修飾符,故可以省略);
- 接口里的方法只能為抽象方法(沒有方法體)、類方法(必須使用static修飾,有方法體,Java 8及以上版本支持)、默認方法(必須使用default修飾,有方法體,Java 8及以上版本支持);
- 一個接口可以從多個接口得到繼承(即接口允許多繼承,類只能單繼承),但不允許接口從類得到繼承(即接口只能繼承接口);
- 接口不能被實例化。
接口的語法格式
[修飾符] interface 接口名 { 定義零到多個常量... 定義零到多個抽象方法... 定義零到多個內(nèi)部類、接口、枚舉... 定義零到多個默認方法、類方法(Java 8+)... }
??修飾符可以是public或者省略,省略的話默認為default(即包權限)。
接口的用途
- 定義變量,也可以用于進行強制類型轉(zhuǎn)換
- 調(diào)用接口中定義的常量
- 被其它類實現(xiàn)
實現(xiàn)接口
1. 一個類只能繼承一個類,但可以實現(xiàn)(implements)一個或多個接口(即單繼承,多實現(xiàn));
2. 一個類實現(xiàn)接口后,必須實現(xiàn)接口里的所有抽象方法,否則這個類就成為一個抽象類。
簡單工廠模式(Simple Factory Pattern)
1. 簡單工廠模式,又叫靜態(tài)工廠方法(Static Factory Method)模式;
2. 簡單工廠模式是由一個工廠對象根據(jù)傳入的參數(shù),動態(tài)地決定創(chuàng)建出哪一種產(chǎn)品類的實例(這產(chǎn)品類往往繼承自同一個父類或?qū)崿F(xiàn)了同一個接口)。
簡單工廠模式包含的角色及職責
工廠(Creator)角色
??簡單工廠模式的核心,它負責實現(xiàn)創(chuàng)建所有實例的內(nèi)部邏輯。工廠類創(chuàng)建產(chǎn)品類的方法可以被外界直接調(diào)用,創(chuàng)建所需的產(chǎn)品對象。
抽象產(chǎn)品(Product)角色
??簡單工廠模式所創(chuàng)建的所有對象的父類(父類可以是接口或抽象類),它負責描述所有實例所共有的公共接口。
具體產(chǎn)品(Concrete Product)角色
??簡單工廠模式所創(chuàng)建的具體實例對象。
具體例子:

上面定義了一個Printer接口,在其內(nèi)部定義了三個抽象方法。

上面定義了一個HPPrinter類,其實現(xiàn)了Printer接口并重寫了Printer接口的全部抽象方法。

上面定義了一個CanonPrinter 類,其實現(xiàn)了Printer接口并重寫了Printer接口的全部抽象方法。

上面定義了一個PrinterFactory類,其有一個返回值類型為Printer的靜態(tài)方法,根據(jù)用戶傳入的不同參數(shù)創(chuàng)建不同的實例。

上面定義了一個測試類,用來測試程序。
運行結(jié)果:


從上面的運行結(jié)果可以看到,當用戶輸入不同的參數(shù)時,會得到不同的打印機。
簡單工廠模式的優(yōu)缺點
優(yōu)點:
??工廠類是整個模式的關鍵所在。它包含必要的判斷邏輯,能夠根據(jù)外界給定的信息,決定究竟應該創(chuàng)建哪個具體類的對象。用戶在使用時可以直接根據(jù)工廠類去創(chuàng)建所需的實例,而無需了解這些對象是如何創(chuàng)建以及如何組織的。這有利于整個軟件體系結(jié)構(gòu)的優(yōu)化。
缺點:
??由于工廠類集中了所有實例的創(chuàng)建邏輯,將全部創(chuàng)建邏輯集中到了一個工廠類中,導致沒有很高的內(nèi)聚性;同時,工廠類違反了開閉原則,它所能創(chuàng)建的類只能是事先考慮到的,如果需要添加新的類,那就需要改變工廠類了。
參考資料: