抽象方法和抽象類(abstract)
- 抽象方法和抽象類使用 abstract 來定義哑子,有抽象方法的類必須被定義為抽象類,抽象類里可以沒有抽象方法奉芦;
- 抽象方法:只有方法簽名赵抢,沒有方法體的方法;
- 抽象類不能被實(shí)例化声功,也就是不能通過new關(guān)鍵字去產(chǎn)生對(duì)象烦却,只能被繼承,但是可以定義變量先巴,任何繼承了抽象類的非抽象類的對(duì)象可以給這個(gè)變量賦值其爵;
- 抽象類的子類必須實(shí)現(xiàn)抽象類里的所有抽象方法,否則這個(gè)子類還是抽象類伸蚯;
- 抽象類可以包含成員變量摩渺、方法(普通方法和抽象方法)、構(gòu)造器(并不用于創(chuàng)建對(duì)象剂邮,而是讓子類調(diào)用摇幻,從而完成屬于抽象類的初始化操作)、初始化塊挥萌、內(nèi)部類(接口绰姻、枚舉)。
抽象類的作用
抽象類是從多個(gè)具有相同特征的具體類中抽象出來的父類引瀑,以這個(gè)父類作為子類的模板狂芋,可以避免子類設(shè)計(jì)的隨意性。
模板方法模式(Template Method)
1. 模板方法模式是由抽象父類控制頂級(jí)邏輯憨栽,并把某些操作的實(shí)現(xiàn)推遲到子類去實(shí)現(xiàn)帜矾。
2. 如果編寫一個(gè)抽象父類翼虫,父類將部分邏輯以具體方法以及具體構(gòu)造函數(shù)的形式實(shí)現(xiàn),并把不能實(shí)現(xiàn)的部分抽成抽象方法屡萤,留給其子類去實(shí)現(xiàn)珍剑,不同的子類可以以不同的方式實(shí)現(xiàn)這些抽象方法,從而對(duì)剩余的邏輯有不同的實(shí)現(xiàn)灭衷,這種模式就叫模板方法模式次慢。
具體例子:
上面定義了一個(gè)抽象的SpeedMeter類,用來計(jì)算車速翔曲。該類定義了兩個(gè)子類通用的方法——設(shè)置轉(zhuǎn)速的方法setTurnRate()和計(jì)算車速的方法getSpeed(),getSpeed()方法需要知道車輪的半徑劈愚,但SpeedMeter并不知道車輪的半徑瞳遍,所以將其抽象成抽象方法,交由子類來實(shí)現(xiàn)菌羽。
上面定義了CarSpeedMeter類和BicycleSpeedMeter類掠械,它們均繼承自SpeedMeter類,并實(shí)現(xiàn)了其父類中的抽象方法getRadius()注祖,其中CarSpeedMeter類的半徑是0.31m猾蒂,BicycleSpeedMeter類的半徑是0.33m。
上面定義了一個(gè)測(cè)試類是晨,分別創(chuàng)建了CarSpeedMeter類和BicycleSpeedMeter類的對(duì)象肚菠,并分別設(shè)置它們的轉(zhuǎn)速,最后打印它們各自的車速罩缴。
運(yùn)行結(jié)果:
模板方法模式(Template Method)的應(yīng)用場(chǎng)景
- 具有統(tǒng)一的操作步驟或操作過程
- 具有不同的操作細(xì)節(jié)
- 存在多個(gè)具有同樣操作步驟的應(yīng)用場(chǎng)景蚊逢,但某些具體的操作細(xì)節(jié)卻各不相同
接口(interface)
- 接口里可以包含成員變量、方法箫章、內(nèi)部類(包括內(nèi)部接口和枚舉)烙荷,不能有構(gòu)造器和初始化塊;
- 接口里的成員變量必須初始化(即必須賦初值)檬寂,且均為靜態(tài)常量(即此值一旦賦值便不能再更改终抽,系統(tǒng)會(huì)自動(dòng)為成員變量添加static和final修飾符,故可以省略)桶至;
- 接口里的方法只能為抽象方法(沒有方法體)昼伴、類方法(必須使用static修飾,有方法體塞茅,Java 8及以上版本支持)亩码、默認(rèn)方法(必須使用default修飾,有方法體野瘦,Java 8及以上版本支持)描沟;
- 一個(gè)接口可以從多個(gè)接口得到繼承(即接口允許多繼承飒泻,類只能單繼承),但不允許接口從類得到繼承(即接口只能繼承接口)吏廉;
- 接口不能被實(shí)例化泞遗。
接口的語法格式
[修飾符] interface 接口名 { 定義零到多個(gè)常量... 定義零到多個(gè)抽象方法... 定義零到多個(gè)內(nèi)部類、接口席覆、枚舉... 定義零到多個(gè)默認(rèn)方法史辙、類方法(Java 8+)... }
??修飾符可以是public或者省略,省略的話默認(rèn)為default(即包權(quán)限)佩伤。
接口的用途
- 定義變量聊倔,也可以用于進(jìn)行強(qiáng)制類型轉(zhuǎn)換
- 調(diào)用接口中定義的常量
- 被其它類實(shí)現(xiàn)
實(shí)現(xiàn)接口
1. 一個(gè)類只能繼承一個(gè)類,但可以實(shí)現(xiàn)(implements)一個(gè)或多個(gè)接口(即單繼承生巡,多實(shí)現(xiàn))耙蔑;
2. 一個(gè)類實(shí)現(xiàn)接口后,必須實(shí)現(xiàn)接口里的所有抽象方法孤荣,否則這個(gè)類就成為一個(gè)抽象類甸陌。
簡(jiǎn)單工廠模式(Simple Factory Pattern)
1. 簡(jiǎn)單工廠模式,又叫靜態(tài)工廠方法(Static Factory Method)模式盐股;
2. 簡(jiǎn)單工廠模式是由一個(gè)工廠對(duì)象根據(jù)傳入的參數(shù)钱豁,動(dòng)態(tài)地決定創(chuàng)建出哪一種產(chǎn)品類的實(shí)例(這產(chǎn)品類往往繼承自同一個(gè)父類或?qū)崿F(xiàn)了同一個(gè)接口)。
簡(jiǎn)單工廠模式包含的角色及職責(zé)
工廠(Creator)角色
??簡(jiǎn)單工廠模式的核心疯汁,它負(fù)責(zé)實(shí)現(xiàn)創(chuàng)建所有實(shí)例的內(nèi)部邏輯牲尺。工廠類創(chuàng)建產(chǎn)品類的方法可以被外界直接調(diào)用,創(chuàng)建所需的產(chǎn)品對(duì)象涛目。
抽象產(chǎn)品(Product)角色
??簡(jiǎn)單工廠模式所創(chuàng)建的所有對(duì)象的父類(父類可以是接口或抽象類)秸谢,它負(fù)責(zé)描述所有實(shí)例所共有的公共接口。
具體產(chǎn)品(Concrete Product)角色
??簡(jiǎn)單工廠模式所創(chuàng)建的具體實(shí)例對(duì)象霹肝。
具體例子:
上面定義了一個(gè)Printer接口估蹄,在其內(nèi)部定義了三個(gè)抽象方法。
上面定義了一個(gè)HPPrinter類沫换,其實(shí)現(xiàn)了Printer接口并重寫了Printer接口的全部抽象方法臭蚁。
上面定義了一個(gè)CanonPrinter 類,其實(shí)現(xiàn)了Printer接口并重寫了Printer接口的全部抽象方法讯赏。
上面定義了一個(gè)PrinterFactory類垮兑,其有一個(gè)返回值類型為Printer的靜態(tài)方法,根據(jù)用戶傳入的不同參數(shù)創(chuàng)建不同的實(shí)例漱挎。
上面定義了一個(gè)測(cè)試類系枪,用來測(cè)試程序。
運(yùn)行結(jié)果:
從上面的運(yùn)行結(jié)果可以看到磕谅,當(dāng)用戶輸入不同的參數(shù)時(shí)私爷,會(huì)得到不同的打印機(jī)雾棺。
簡(jiǎn)單工廠模式的優(yōu)缺點(diǎn)
優(yōu)點(diǎn):
??工廠類是整個(gè)模式的關(guān)鍵所在。它包含必要的判斷邏輯衬浑,能夠根據(jù)外界給定的信息捌浩,決定究竟應(yīng)該創(chuàng)建哪個(gè)具體類的對(duì)象。用戶在使用時(shí)可以直接根據(jù)工廠類去創(chuàng)建所需的實(shí)例工秩,而無需了解這些對(duì)象是如何創(chuàng)建以及如何組織的尸饺。這有利于整個(gè)軟件體系結(jié)構(gòu)的優(yōu)化。
缺點(diǎn):
??由于工廠類集中了所有實(shí)例的創(chuàng)建邏輯助币,將全部創(chuàng)建邏輯集中到了一個(gè)工廠類中浪听,導(dǎo)致沒有很高的內(nèi)聚性;同時(shí)奠支,工廠類違反了開閉原則馋辈,它所能創(chuàng)建的類只能是事先考慮到的,如果需要添加新的類倍谜,那就需要改變工廠類了。
參考資料: