final+模版設計模式的理解

模板設計模式在 Java 里是一種行為設計模式,它在抽象類里定義算法的骨架,把部分步驟的具體實現延遲到子類。如此一來,子類可以在不改變算法結構的基礎上,重新定義算法中的特定步驟。

模式組成

抽象類(Abstract Class):定義了算法的骨架,其中包含模板方法與抽象方法。模板方法是具體方法,它規定了算法的步驟,并且會調用抽象方法;抽象方法則由子類去實現。 ?

具體子類(Concrete Subclass):實現抽象類中的抽象方法,完成算法中特定步驟的具體操作。 代碼示例

下面是一個用 Java 實現模板設計模式的示例,以制作飲料為例:

// 抽象類
abstract class Beverage {// 模板方法,定義制作飲料的算法骨架public final void prepareBeverage() {boilWater();brew();pourInCup();addCondiments();}public void boilWater() {System.out.println("Boiling water");}public void pourInCup() {System.out.println("Pouring into cup");}// 抽象方法,由子類實現public abstract void brew();public abstract void addCondiments();
}// 具體子類:咖啡
class Coffee extends Beverage {@Overridepublic void brew() {System.out.println("Dripping coffee through filter");}@Overridepublic void addCondiments() {System.out.println("Adding sugar and milk");}
}// 具體子類:茶
class Tea extends Beverage {@Overridepublic void brew() {System.out.println("Steeping the tea");}@Overridepublic void addCondiments() {System.out.println("Adding lemon");}
}// 測試類
public class TemplatePatternDemo {public static void main(String[] args) {Beverage coffee = new Coffee();System.out.println("Making coffee:");coffee.prepareBeverage();System.out.println("\nMaking tea:");Beverage tea = new Tea();tea.prepareBeverage();}
}

代碼解釋

Beverage類屬于抽象類,prepareBeverage方法是模板方法,它定義了制作飲料的通用步驟。brew和addCondiments是抽象方法,要由子類來實現。

Coffee和Tea類為具體子類,它們實現了brew和addCondiments方法,完成了制作咖啡和茶的特定步驟。

優點

代碼復用:模板方法定義了算法的骨架,避免了在多個子類中重復編寫相同的代碼。

可擴展性:子類能夠根據需求重寫抽象方法,實現自身的業務邏輯。

缺點

類數量增加:每一個不同的實現都需要一個子類,這可能會導致類的數量增加,使系統更加復雜。 靈活性受限:由于模板方法定義了算法的骨架,子類只能在特定的步驟上進行擴展,可能會限制算法的靈活性。




public final void prepareBeverage(),final修飾里面的方法,不能重寫,里面的方法卻能重寫,我很混亂,通俗易懂解釋一下




在模板方法模式中,prepareBeverage()?被聲明為?final?是為了確保算法的整體流程不被子類修改,而內部的?brew()?和?addCondiments()?被聲明為?abstract?是為了強制子類實現具體的細節。這種設計實現了“固定流程,靈活擴展”的效果。


通俗解釋:

  1. 為什么用?final
    prepareBeverage()?是制作飲料的固定流程(燒水 → 沖泡 → 倒杯 → 加調料),用?final?表示“這個流程不能被子類篡改”。比如,子類不能把順序改成“先加調料再燒水”。

  2. 為什么內部的?brew()?和?addCondiments()?可以重寫?
    這兩個方法是抽象方法(abstract),子類必須實現它們。父類只定義流程(“要沖泡”和“要加調料”),但具體怎么沖泡、加什么調料,由子類自己決定。例如:

    • 咖啡沖泡是“用濾紙滴漏”,加“糖和牛奶”。

    • 茶沖泡是“用熱水浸泡茶葉”,加“檸檬”。


類比現實場景:

想象一個“烹飪機器人”的模板:

  1. 固定流程(final?方法):
    它的做菜步驟是固定的:開火 → 放食材 → 翻炒 → 關火。

  2. 靈活擴展(抽象方法):
    但具體“放什么食材”、“怎么翻炒”由用戶決定(比如做西紅柿炒蛋還是青椒肉絲)。


代碼驗證:

如果子類嘗試重寫?prepareBeverage(),會直接編譯報錯:

class Coffee extends Beverage {// ? 編譯錯誤!不能重寫 final 方法@Overridepublic void prepareBeverage() { // 非法操作!}
}

但子類必須實現抽象方法:

class Coffee extends Beverage {@Overridepublic void brew() { /* 必須實現 */ }      // ?@Overridepublic void addCondiments() { /* 必須實現 */ } // ?
}

總結:

  • final?方法:保護算法流程的完整性(“怎么做”)。

  • abstract?方法:定義子類必須實現的擴展點(“做什么”)。

這就是模板方法模式的核心:在父類控制流程,在子類實現細節

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

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

相關文章

JAVA接口調用限速器

目錄 1、并發限速 2、串行限速 需求:批量調用第三方ERP接口,對方接口限流時,減緩調用速率。 1、并發限速 Slf4j RestController public class ApiCallTask {//第三方接口Resourceprivate ErpService erpService;//異步線程池Resourcepriv…

STM32 CAN控制器硬件資源與用法

1、硬件結構圖 以STM32F4為例,他有2個can控制器,分別為 CAN1 CAN2。 每個CAN控制器,都有3個發送郵箱、2個接收fifo,每個接收fifo又由3個接收郵箱組成。也即每個CAN控制器都有9個郵箱,其中3個供發送用,3個…

【C++ 繼承】—— 青花分水、和而不同,繼承中的“明明德”與“止于至善”

歡迎來到ZyyOvO的博客?,一個關于探索技術的角落,記錄學習的點滴📖,分享實用的技巧🛠?,偶爾還有一些奇思妙想💡 本文由ZyyOvO原創??,感謝支持??!請尊重原創&#x1…

Qt warning LNK4042: 對象被多次指定;已忽略多余的指定

一、常規原因: pro或pri 文件中源文件被多次包含 解決:刪除變量 SOURCES 和 HEADERS 中重復條目 二、誤用 對于某些pri庫可以使用如下代碼簡寫包含 INCLUDEPATH $$PWDHEADERS $$PWD/*.hSOURCES $$PWD/*.cpp但是假如該目錄下只有頭文件,沒…

Visual Studio Code 無法打開源文件解決方法

🌈 個人主頁:Zfox_ 🔥 系列專欄:Linux 🔥 系列專欄:C從入門到精通 目錄 一:🔥 突發狀況 二:🔥 共勉 一:🔥 突發狀況 🐬…

js文字兩端對齊

目錄 一、問題 二、原因及解決方法 三、總結 一、問題 1.text-align: justify; 不就可以了嗎?但是實際測試無效 二、原因及解決方法 1.原因:text-align只對非最后一行文字有效。只有一行文字時,text-align無效,要用text-alig…

LeetCode算法題(Go語言實現)_20

題目 給你兩個下標從 0 開始的整數數組 nums1 和 nums2 ,請你返回一個長度為 2 的列表 answer ,其中: answer[0] 是 nums1 中所有 不 存在于 nums2 中的 不同 整數組成的列表。 answer[1] 是 nums2 中所有 不 存在于 nums1 中的 不同 整數組成…

每天認識一個設計模式-橋接模式:在抽象與實現的平行宇宙架起彩虹橋

一、前言:虛擬機橋接的啟示 使用過VMware或者Docker的同學們應該都接觸過網絡橋接,在虛擬機網絡配置里,橋接模式是常用的網絡連接方式。選擇橋接模式時,虛擬機會通過虛擬交換機與物理網卡相連,獲取同網段 IP 地址&…

java筆記02

運算符 1.隱式轉換和強制轉換 類型轉換的分類 1.隱式轉換: 取值范圍小的數值 轉換為 取值范圍大的數值 2.強制轉換: 取值范圍大的數值 轉換為 取值范圍小的數值隱式轉換的兩種提升規則 取值范圍小的,和取值范圍大的進行運算,小的…

Redis-07.Redis常用命令-集合操作命令

一.集合操作命令 SADD key member1 [member2]: sadd set1 a b c d sadd set1 a 0表示沒有添加成功,因為集合中已經有了這個元素了,因此無法重復添加。 SMEMBERS key: smembers set1 SCARD key: scard set1 SADD key member1 …

李飛飛、吳佳俊團隊新作:FlowMo如何以零卷積、零對抗損失實現ImageNet重構新巔峰

目錄 一、摘要 二、引言 三、相關工作 四、方法 基于擴散先前的離散標記化器利用廣告 架構 階段 1A:模式匹配預訓練 階段 1B:模式搜索后訓練 采樣 第二階段:潛在生成建模 五、Coovally AI模型訓練與應用平臺 六、實驗 主要結果 …

CSS3:現代Web設計的魔法卷軸

一、布局革命:從平面到多維空間 1.1 Grid布局的次元突破 星際戰艦布局系統 .galaxy {display: grid;grid-template-areas: "nav nav nav""sidebar content ads""footer footer footer";grid-template-rows: 80px 1fr 120p…

美觀快速的react 的admin框架

系統特色: - 🎨 精心設計的UI主題系統,提供優雅的配色方案和視覺體驗 - 📦 豐富完整的組件庫,包含大量開箱即用的高質量組件 - 🔨 詳盡的組件使用示例,降低開發者的學習成本 - &#x1f680…

【C++】 string底層封裝的模擬實現

目錄 前情提要Member functions —— 成員函數構造函數拷貝構造函數賦值運算符重載析構函數 Element access —— 元素訪問Iterator —— 迭代器Capacity —— 容量sizecapacityclearemptyreserveresize Modifiers —— 修改器push_backappendoperator(char ch)operator(const …

計算機網絡相關知識小結

計算機網絡 1.計算機網絡:獨立計算機,通信線路連接,實現資源共享 2.組成:資源子網和通信子網 3.拓撲分類 4.范圍:LAN, MAN. WAN 5、有線和無線 6.按照方向:單工、雙工,全雙工 7.傳輸對象方式&a…

16-CSS3新增選擇器

知識目標 掌握屬性選擇器的使用掌握關系選擇器的使用掌握結構化偽類選擇器的使用掌握偽元素選擇器的使用 如何減少文檔內class屬性和id屬性的定義,使文檔變得更加簡潔? 可以通過屬性選擇器、關系選擇器、結構化偽類選擇器、偽元素選擇器。 1. 屬性選擇…

【彈性計算】異構計算云服務和 AI 加速器(四):FPGA 虛擬化技術

《異構計算云服務和 AI 加速器》系列,共包含以下文章: 異構計算云服務和 AI 加速器(一):功能特點異構計算云服務和 AI 加速器(二):適用場景異構計算云服務和 AI 加速器(…

Java進階——位運算

位運算直接操作二進制位,在處理底層數據、加密算法、圖像處理等領域具有高效性能和效率。本文將深入探討Java中的位運算。 本文目錄 一、位運算簡介1. 與運算2. 或運算異或運算取反運算左移運算右移運算無符號右移運算 二、位運算的實際應用1. 權限管理2. 交換兩個變…

OpenAI深夜直播「偷襲」谷歌!GPT-4o原生圖像生成:奧特曼帶梗圖,AGI戰場再燃戰火

引言:AI戰場的「閃電戰」 當谷歌剛剛發布「地表最強」Gemini 2.5 Pro時,OpenAI立即以一場深夜直播「閃電反擊」——GPT-4o的原生圖像生成功能正式上線!從自拍變梗圖到相對論漫畫,奧特曼(OpenAI團隊)用一連…

鴻蒙harmonyOS:筆記 正則表達式

從給出的文本中,按照既定的相關規則,匹配出符合的數據,其中的規則就是正則表達式,使用正則表達式,可以使得我們用簡潔的代碼就能實現一定復雜的邏輯,比如判斷一個郵箱賬號是否符合正常的郵箱賬號&#xff0…