抽象類、模板方法模式

抽象類概述

在Java中abstract是抽象的意思,如果一個類中的某個方法的具體實現不能確定,就可以申明成abstract修飾的抽象方法(不能寫方法體了),這個類必須用abstract修飾,被稱為抽象類。

抽象方法定義:修飾符 abstract 返回值類型 方法名稱(形參列表);,只有方法簽名,沒有方法體,使用了abstract修飾。

抽象類定義:修飾符 abstract class 類名{ ?}

抽象類可以理解成類的不完整設計圖,是用來被子類繼承的。

抽象類的作用: 可以被子類繼承、充當模板的、同時也可以提高代碼復用。

示例:

public abstract class Animal {private String name;public abstract void run();public String getName() {return name;}public void setName(String name) {this.name = name;}
}

抽象類的案例

系統需求

某加油站推出了2種支付卡,一種是預存10000的金卡,后續加油享受8折優惠,另一種是預存5000的銀卡 ,后續加油享受8.5折優惠。

請分別實現2種卡片進入收銀系統后的邏輯,卡片需要包含主人名稱,余額,支付功能。

分析實現

創建一張卡片父類:定義屬性包括主人名稱、余額、支付功能(具體實現交給子類)

創建一張白金卡類:重寫支付功能,按照原價的8折計算輸出。 創建一張銀卡類:重寫支付功能,按照原價的8.5折計算輸出。

代碼

/**抽象父類*/
public abstract class Card {private String name; // 主人名稱private double money;/**子類一定要支付的,但是每個子類支付的情況不一樣,所以父類把支付定義成抽象方法,交給具體子類實現*/public abstract void pay(double money);public String getName() {return name;}public void setName(String name) {this.name = name;}public double getMoney() {return money;}public void setMoney(double money) {this.money = money;}
}
/**金卡*/
public class GoldCard extends Card{@Overridepublic void pay(double money) {// 優惠后的金額算出來:double rs = money * 0.8;double lastMoney = getMoney() - rs;System.out.println(getName() + "當前賬戶總金額:"+ getMoney() +",當前消費了:" + rs +",消費后余額剩余:" +lastMoney);setMoney(lastMoney); // 更新賬戶對象余額}
}

?銀卡差不多

抽象類的特征、注意事項

1、有得有失: 得到了抽象方法,失去了創建對象的能力。

2、抽象類為什么不能創建對象?? 反證法。

3、類有的成員(成員變量、方法、構造器)抽象類都具備

4、抽象類中不一定有抽象方法,有抽象方法的類一定是抽象類

5、一個類繼承了抽象類必須重寫完抽象類的全部抽象方法,否則這個類也必須定義成抽象類。

6、不能用abstract修飾變量、代碼塊、構造器。

final和abstract是什么關系?

互斥關系

abstract定義的抽象類作為模板讓子類繼承,final定義的類不能被繼承。

抽象方法定義通用功能讓子類重寫,final定義的方法子類不能重寫。

抽象類的應用知識:模板方法模式

概述

模板方法模式(Template Method Pattern)是一種行為設計模式,它在一個方法中定義一個算法的骨架,允許子類在不改變算法結構的情況下重新定義某些步驟的具體內容。換句話說,模板方法模式封裝了不變的部分,而將可變的部分留給子類來實現。

在模板方法模式中,通常有一個抽象類(或稱為模板類),它定義了算法的骨架和步驟的順序。這個抽象類還包含一些抽象方法或鉤子方法(hook methods),這些方法是抽象的,需要在子類中具體實現。子類通過實現這些抽象方法,可以重新定義算法中的某些步驟,以滿足特定的需求。

使用模板方法模式的好處有以下幾點:

  1. 代碼復用:模板方法模式將算法的不變部分封裝在父類中,而可變部分則留給子類來實現。這樣,子類可以在不改變算法結構的情況下,通過覆蓋父類的方法來實現自己的邏輯,從而實現了代碼的復用。
  2. 擴展性:由于算法的可變部分被抽象出來,子類可以通過擴展父類來實現新的功能。這符合開閉原則,即對擴展開放,對修改封閉。
  3. 控制子類行為:模板方法模式通過定義算法的骨架和步驟順序,可以控制子類的行為。父類中的模板方法規定了算法的整體流程,而子類則通過實現抽象方法來參與這個流程。

然而,模板方法模式也有一些潛在的缺點:

  1. 類個數增加:對于每個不同的實現,都需要定義一個子類,這可能會導致類的個數增加,系統更加龐大和復雜。
  2. 反向控制結構:父類中的抽象方法由子類實現,子類執行的結果會影響父類的結果,這導致一種反向的控制結構。這可能會增加代碼閱讀的難度和維護的復雜性。

在實際應用中,模板方法模式通常用于實現一些具有固定流程的操作,如文件操作、數據庫操作、網絡通信等。在這些場景中,通過使用模板方法模式,可以將不變的部分封裝起來,而將可變的部分留給子類來實現,從而提高代碼的復用性和可維護性。

什么時候使用模板方法模式

使用場景說明:當系統中出現同一個功能多處在開發,而該功能中大部分代碼是一樣的,只有其中部分可能不同的時候。

模板方法模式實現步驟

把功能定義成一個所謂的模板方法,放在抽象類中,模板方法中只定義通用且能確定的代碼。

模板方法中不能確定的功能定義成抽象方法讓具體子類去實現。

案例:銀行利息結算系統

需求:

某軟件公司要為某銀行的業務支撐系統開發一個利息結算系統,賬戶有活期和定期賬戶兩種。

活期是0.35%,定期是 1.75%,定期如果滿10萬額外給予3%的收益。

結算利息要先進行用戶名、密碼驗證,驗證失敗直接提示,登錄成功進行結算。

分析:

實現步驟:

創建一個抽象的賬戶類Account作為父類模板,提供屬性(卡號,余額)。

在父類Account中提供一個模板方法實現登錄驗證,利息結算、利息輸出。

具體的利息結算定義成抽象方法,交給子類實現。

定義活期賬戶類,讓子類重寫實現具體的結算方法。

定義定期賬戶類,讓子類重寫實現具體的結算方法。

創建賬戶對象,完成相關功能。

代碼:

public abstract class Account {private String cardId;private double money;public Account() {}public Account(String cardId, double money) {this.cardId = cardId;this.money = money;}/**模板方法*/public final void handle(String loginName , String passWord ){// a.判斷登錄是否成功if("itheima".equals(loginName) && "123456".equals(passWord)){System.out.println("登錄成功。。");// b.正式結算利息// 當前模板方法知道所有子類賬戶都要結算利息,但是具體怎么結算,模板不清楚,交給具體的子類來計算double result = calc();// c.輸出利息詳情System.out.println("本賬戶利息是:"+ result);}else{System.out.println("用戶名或者密碼錯誤了");}}public abstract double calc();public String getCardId() {return cardId;}public void setCardId(String cardId) {this.cardId = cardId;}public double getMoney() {return money;}public void setMoney(double money) {this.money = money;}
}
/**活期賬戶*/
public class CurrentAccount extends Account {public CurrentAccount(String cardId,  double money) {super(cardId, money);}@Overridepublic double calc() {// b.正式結算利息double result =  getMoney() * 0.0175; // 結算利息了return result;}}
public class Test {public static void main(String[] args) {CurrentAccount acc = new CurrentAccount("ICBC-111", 100000);acc.handle("itheima", "123456");}
}

模板方法我們是建議使用final修飾的,這樣會更專業,那么為什么呢?

答:模板方法是給子類直接使用的,不是讓子類重寫的, 一旦子類重寫了模板方法就失效了。

模板方法模式解決了什么問題? ?

極大的提高了代碼的復用性。

模板方法已經定義了通用結構,模板不能確定的定義成抽象方法。 ?

使用者只需要關心自己需要實現的功能即可。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/711887.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/711887.shtml
英文地址,請注明出處:http://en.pswp.cn/news/711887.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【解決】修改 UI界面渲染層級 的常見誤區

開發平臺:Unity 2021版本 ? 問題描述 Unity 中管理 UI 上顯示元素的前后層級關系大致為以下兩種方式: 方式一:修改UI元素隊列順序與層級方式二:使用 Canvas 組件中的 Override Sort 屬性配置 方式二 對應復雜的 UI 層級關系將常…

這些單片機匯編語言的錯誤,你還在犯錯嗎?

在單片機開發中,很多工程師會選擇匯編語言來作為底層編程,來直接控制硬件和高校執行命令,然而因為匯編語言是直接與硬件交互,所以很容易出現錯誤,本文將基于Keil C51匯編器的環境總結單片機匯編語言常見的錯誤&#xf…

人工智能_大模型010_Centos7.9中CPU安裝ChatGLM3-6B大模型_安裝使用_010---人工智能工作筆記0145

從一個空的虛擬機開始安裝: https://www.modelscope.cn/models/ZhipuAI/chatglm3-6b/files 可以看到這里有很多的數據文件,那么這里 這里點擊模型文件就可以下載,這個就是chatglm3-6B的文件,需要點擊每個文件,然后點擊右邊的下載,把文件都下載下來 右側有下載按鈕.點擊下載可…

使用Fabric創建的canvas畫布背景圖片,自適應畫布寬高

之前的文章寫過vue2使用fabric實現簡單畫圖demo,完成批閱功能;但是功能不完善,對于很大的圖片就只能顯示一部分出來,不符合我們的需求。這就需要改進,對我們設置的背景圖進行自適應。 有問題的canvas畫布背景 修改后的…

Unity2023.1.19_ECS

Unity2023.1.19_ECS 在學習的路上一往無前的遇到了好東西,官方的EntityComponnentSystemSamples的Repository,這是一個包含實體,圖形,網絡,物理案例的全方位案例教程。 又找見接下來要干的事情了!學習永無…

【rust】11、所有權

文章目錄 一、背景二、Stack 和 Heap2.1 Stack2.2 Heap2.3 性能區別2.4 所有權和堆棧 三、所有權原則3.1 變量作用域3.2 String 類型示例 四、變量綁定背后的數據交互4.1 所有權轉移4.1.1 基本類型: 拷貝, 不轉移所有權4.1.2 分配在 Heap 的類型: 轉移所有權 4.2 Clone(深拷貝)…

Quartz 任務調度框架源碼閱讀解析

概念: quartz 是一個基于JAVA的定時任務調度框架 案例: <dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz</artifactId><version>2.3.0</version></dependency>JobDetail job JobBuilder.newJob(Sc…

每日一練 | 華為認證真題練習Day191

1、在沒有啟用BGP路徑負載分擔的情況下&#xff0c;哪種BGP路由會發送BGP鄰居? A. 從所有鄰居學到的所有BGP路由。 B. 只有從IBGP學到的路由。 C. 只有從EBGP學到的路由。 D. 只有被BGP優選的最佳路由。 2、第三類LSA的LINK ID是 A. 生成這條LSA的路由器的ROUTER ID B. …

LeetCode 刷題 [C++] 第236題.二叉樹的最近公共祖先

題目描述 給定一個二叉樹, 找到該樹中兩個指定節點的最近公共祖先。 百度百科中最近公共祖先的定義為&#xff1a;“對于有根樹 T 的兩個節點 p、q&#xff0c;最近公共祖先表示為一個節點 x&#xff0c;滿足 x 是 p、q 的祖先且 x 的深度盡可能大&#xff08;一個節點也可以…

大數據分析案例-基于SVM支持向量機算法構建手機價格分類預測模型

&#x1f935;?♂? 個人主頁&#xff1a;艾派森的個人主頁 ?&#x1f3fb;作者簡介&#xff1a;Python學習者 &#x1f40b; 希望大家多多支持&#xff0c;我們一起進步&#xff01;&#x1f604; 如果文章對你有幫助的話&#xff0c; 歡迎評論 &#x1f4ac;點贊&#x1f4…

矩陣爆破逆向之條件斷點的妙用

不知道你是否使用過IDA的條件斷點呢&#xff1f;在IDA進階使用中&#xff0c;它的很多功能都有大作用&#xff0c;比如&#xff1a;ida-trace來跟蹤調用流程。同時IDA的斷點功能也十分強大&#xff0c;配合IDA-python的輸出語句能夠大殺特殺&#xff01; 那么本文就介紹一下這…

【JAVA】JDK內置工具之appletviewer

下載java 下載java的時候會先下載Java jdk&#xff0c;Java Development Kit Java開發工具包。 然后會下載jre&#xff0c;也就是Java Runtime Environment Java運行環境。什么是JDK、JRE&#xff1f;_java中的jdk,jre代表什么-CSDN博客 下載之后先找到java下的bin文件&#x…

yolov9 tensorRT 的 C++ 部署

yolov9 tensorRT C 部署 本示例中&#xff0c;包含完整的代碼、模型、測試圖片、測試結果。 完整的代碼、模型、測試圖片、測試結果【github參考鏈接】 TensorRT版本&#xff1a;TensorRT-7.1.3.4 導出onnx模型 導出適配本實例的onnx模型參考【yolov9 瑞芯微芯片rknn部署、地平…

網絡爬蟲的危害,如何有效的防止非法利用

近年來&#xff0c;不法分子利用“爬蟲”軟件收集公民隱私數據案件屢見不鮮。2023年8月23日&#xff0c;北京市高級人民法院召開北京法院侵犯公民個人信息犯罪案件審判情況新聞通報會&#xff0c;通報侵犯公民個人隱私信息案件審判情況&#xff0c;并發布典型案例。在這些典型案…

獲取PDF中的布局信息——如何獲取段落

PDF解析是極其復雜的問題。不可能靠一個工具解決全部問題&#xff0c;尤其是五花八門&#xff0c;格式不統一的PDF文件。除非有鈔能力。如果沒有那就看看可以分為哪些問題。 提取文本內容&#xff0c;提取表格內容&#xff0c;提取圖片。我認為這些應該是分開做的事情。python有…

百度百科數據爬取 python 詞條數據獲取

最近需要補充一些電力名詞的解釋&#xff0c;尤其是文字相關內容。百度百科上的詞條質量有差異&#xff0c;因此我們需要先手工選擇一些高質量詞條。 假設我們選擇了互感器頁面中的儀用變壓器詞條&#xff0c;首先&#xff1a; import requests from bs4 import BeautifulS…

DataSpell 2023:專注于數據,加速您的數據科學之旅 mac/win版

JetBrains DataSpell 2023是一款專為數據科學家和數據分析師設計的集成開發環境&#xff08;IDE&#xff09;。這款IDE提供了強大的數據分析和可視化工具&#xff0c;旨在幫助用戶更快速、更高效地進行數據科學工作。 DataSpell 2023軟件獲取 DataSpell 2023在保持其一貫的數…

【多線程】常見鎖策略詳解(面試常考題型)

目錄 &#x1f334; 樂觀鎖 vs 悲觀鎖&#x1f38d;重量級鎖 vs 輕量級鎖&#x1f340;自旋鎖&#xff08;Spin Lock&#xff09;&#x1f38b;公平鎖 vs ?公平鎖&#x1f333;可重?鎖 vs 不可重?鎖&#x1f384;讀寫鎖?相關面試題 常?的鎖策略 注意: 接下來講解的鎖策略不…

udp丟包問題研究

//發現udp 有收不到數據包現象. 一: 觀察丟包 1. ifconfig enp8s0 2. netstat -s -u 二: 修改系統緩存參數. recv_buffer_size 修改系統buffer_size sysctl -w net.core.rmem_max26214400 sysctl -w net.core.rmem_default26214400 三: 應用程序考慮 av_dict_set(&m_o…

cpp基礎學習筆記03:類型轉換

static_cast 靜態轉換 用于類層次結構中基類和派生類之間指針或者引用的轉換。up-casting (把派生類的指針或引用轉換成基類的指針或者引用表示)是安全的&#xff1b;down-casting(把基類指針或引用轉換成子類的指針或者引用)是不安全的。用于基本數據類型之間的轉換&#xff…