设计模式 模板方法模式

01.如果接到一个任务,要求设计不同型号的悍马车
在这里插入图片描述
02.设计一个悍马车的抽象类(模具,车模)

public abstract class HummerModel {/** 首先,这个模型要能够被发动起来,别管是手摇发动,还是电力发动,反正* 是要能够发动起来,那这个实现要在实现类里了*/public abstract void start(); //能发动,那还要能停下来,那才是真本事public abstract void stop(); //喇叭会出声音,是滴滴叫,还是哔哔叫public abstract void alarm(); //引擎会轰隆隆的响,不响那是假的public abstract void engineBoom(); //那模型应该会跑吧,别管是人推的,还是电力驱动,总之要会跑public abstract void run(); 
} 

03.具体不同版本的悍马,这个是抽象类的具体子类

H1 型号悍马的定义如下:

public class HummerH1Model extends HummerModel { @Override public void alarm() { System.out.println("悍马H1鸣笛..."); } @Overridepublic void engineBoom() { System.out.println("悍马H1引擎声音是这样在..."); } @Overridepublic void start() { System.out.println("悍马H1发动..."); }@Overridepublic void stop() { System.out.println("悍马H1停车..."); } /** 这个方法是很有意思的,它要跑,那肯定要启动,停止了等,也就是要调其他方法*/@Overridepublic void run() { //先发动汽车this.start(); //引擎开始轰鸣this.engineBoom(); //然后就开始跑了,跑的过程中遇到一条狗挡路,就按喇叭this.alarm(); //到达目的地就停车this.stop(); } 
} 

然后看悍马 H2 型号的实现:

public class HummerH2Model extends HummerModel { @Overridepublic void alarm() { System.out.println("悍马H2鸣笛..."); } @Overridepublic void engineBoom() { System.out.println("悍马H2引擎声音是这样在..."); } @Overridepublic void start() { System.out.println("悍马H2发动..."); } @Overridepublic void stop() { System.out.println("悍马H1停车..."); } /** H2要跑,那肯定要启动,停止了等,也就是要调其他方法*/@Overridepublic void run() { //先发动汽车this.start(); //引擎开始轰鸣this.engineBoom(); //然后就开始跑了,跑的过程中遇到一条狗挡路,就按喇叭this.alarm(); //到达目的地就停车this.stop(); } 
}

然后程序写到这里,你就看到问题了,run 方法的实现应该在抽象类上(子类改写的都一样),不应该在实现类上,好,我们修改一下类图和实现:
在这里插入图片描述

就把 run 方法放到了抽象类中,那代码也相应的改变一下,先看 HummerModel.java:

04.修改后的抽象类

public abstract class HummerModel { /** 首先,这个模型要能够被发动起来,别管是手摇发动,还是电力发动,反正* 是要能够发动起来,那这个实现要在实现类里了*/public abstract void start(); //能发动,那还要能停下来,那才是真本事public abstract void stop(); //喇叭会出声音,是滴滴叫,还是哔哔叫public abstract void alarm(); //引擎会轰隆隆的响,不响那是假的public abstract void engineBoom(); //那模型应该会跑吧,别管是人退的,还是电力驱动,总之要会跑public void run() { //先发动汽车this.start(); //引擎开始轰鸣this.engineBoom(); //然后就开始跑了,跑的过程中遇到一条狗挡路,就按喇叭this.alarm(); //到达目的地就停车this.stop(); } 
}

05.修改后的抽象类的子类:

public class HummerH1Model extends HummerModel { @Override public void alarm() { System.out.println("悍马H1鸣笛..."); } @Overridepublic void engineBoom() { System.out.println("悍马H1引擎声音是这样在..."); } @Overridepublic void start() { System.out.println("悍马H1发动..."); }@Overridepublic void stop() { System.out.println("悍马H1停车..."); } } 
public class HummerH2Model extends HummerModel { @Overridepublic void alarm() { System.out.println("悍马H2鸣笛..."); } @Overridepublic void engineBoom() { System.out.println("悍马H2引擎声音是这样在..."); } @Overridepublic void start() { System.out.println("悍马H2发动..."); } @Overridepublic void stop() { System.out.println("悍马H2停车..."); } }

06.运行程序
在这里插入图片描述

public class Client { public static void main(String[] args) { //客户开着H1型号,出去遛弯了HummerModel h1 = new HummerH1Model(); h1.run(); //汽车跑起来了;//客户开H2型号,出去玩耍了HummerModel h2 = new HummerH2Model(); h2.run(); } 
}

在这里插入图片描述

07.客户只要在 run 的过程中,听到或看都成了呀,暴露那么多的方法干啥?把抽象方法保护起来
在这里插入图片描述
把抽象类上的四个方法设置为 protected 访问权限,好了,既然客户不关心这几个方法,而且这四个方法都是由子类来实现的,那就设置成 protected 模式。咦~,那还有个缺陷,run 方法既然子类都不修改,那是不是可以设置成 final 类型呢?是滴是滴,类图如下:
在这里插入图片描述

public abstract class HummerModel { /** 首先,这个模型要能够被发动起来,别管是手摇发动,还是电力发动,反正* 是要能够发动起来,那这个实现要在实现类里了*/protected abstract void start(); //能发动,那还要能停下来,那才是真本事protected abstract void stop(); //喇叭会出声音,是滴滴叫,还是哔哔叫protected abstract void alarm(); //引擎会轰隆隆的响,不响那是假的protected abstract void engineBoom(); //那模型应该会跑吧,别管是人退的,还是电力驱动,总之要会跑final public void run() { //先发动汽车this.start(); //引擎开始轰鸣this.engineBoom(); //然后就开始跑了,跑的过程中遇到一条狗挡路,就按喇叭this.alarm(); //到达目的地就停车this.stop(); } 
} 

大家请看这个 run 方法,他定义了调用其他方法的顺序,并且子类是不能修改的,这个叫做模板方法;start、stop、alarm、engineBoom 这四个方法是子类必须实现的,而且这四个方法的修改对应了不同的类,这个叫做基本方法,基本方法又分为三种:在抽象类中实现了的基本方法叫做具体方法;在抽象类中没有实现,在子类中实现了叫做抽象方法,我们这四个基本方法都是抽象方法,由子类来实现的;还有一种叫做钩子方法,

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/280966.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

鸿蒙Harmony应用开发—ArkTS-全局UI方法(列表选择弹窗)

列表弹窗。 说明: 从API Version 8开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 本模块功能依赖UI的执行上下文,不可在UI上下文不明确的地方使用,参见UIContext说明。 从API version 10开始&#xff0…

什么是VR应急预案演练虚拟化|VR体验馆加盟|元宇宙文旅

VR 应急预案演练虚拟化指的是利用虚拟现实(Virtual Reality,VR)技术进行应急预案演练的过程。在传统的应急预案演练中,人们通常需要在实际场地或模拟环境中进行演练,这可能存在一些限制,如成本高昂、场地受…

C语言每日一题06

一、题目 二、解析 void main () { char c1,c2; int a1,a2; c1 getchar ();//读取第一个输入,c11 scanf (“%3d”,&a1&#xff…

MNN createSession 之创建流水线后端(四)

系列文章目录 MNN createFromBuffer(一) MNN createRuntime(二) MNN createSession 之 Schedule(三) MNN createSession 之创建流水线后端(四) MNN Session 之维度计算(五…

CSS学习(2)-盒子模型

1. CSS 长度单位 px :像素。em :相对元素 font-size 的倍数。rem :相对根字体大小,html标签就是根。% :相对父元素计算。 注意: CSS 中设置长度,必须加单位,否则样式无效&#xff…

19---时钟电路设计

视频链接 时钟硬件电路设计01_哔哩哔哩_bilibili 时钟电路设计 晶振是数字电路的心脏,数字电路需要一个稳定的工作时钟信号,时钟电路至关重要! 1、晶振概述 晶振一般指晶体振荡器。晶体振荡器是指从一块石英晶体上按一定方位角切下薄片&…

python课后习题一

题目: 1. 2. 解题过程: 1. """计算年数和天数""" minute int(input("请输入分钟数:")) hours minute // 60 days hours // 24 years days // 365 last_days days % 365 print(f"{minut…

kafka集群介绍及搭建

介绍 kafka是一个高性能、低延迟、分布式的消息传递系统,特点在于实时处理数据。集群由多个成员节点broker组成,每个节点都可以独立处理消息传递和存储任务。 路由策略 发布消息由key、value组成,真正的消息是value,key是标识路…

使用Pygame做一个乒乓球游戏

项目介绍 使用Pygame做一个乒乓球游戏。左侧为电脑,右侧为玩家。 视频地址-YT 视频搬运-B站 视频教程约90分钟。 代码地址 环境:需要pygame库,可用pip安装:pip install pygame 1. 基础版本 首先进行一些初始化,初始…

PHP全新美化广告横幅在线制作源码

源码简介 可以做网站的引流不需要安装上传就可以使用,在第一版基础上做了二次开发更加好用 注意:主机和服务器均可架设搭建,如果使用宝塔架设点击访问的时候提示找不到文件路径的时候,记得点击网站目录把防跨站攻击先关闭,这样就可以正常访问了,这款是…

海格里斯HEGERLS托盘搬运机器人四向车引领三维空间集群设备柔性运维

随着市场的不断迅猛发展变化,在物流仓储中,无论是国内还是海外,都对托盘式解决方案需求量很大。顾名思义,托盘式解决方案简单理解就是将产品放置在托盘上进行存储、搬运和拣选。 面对托盘式方案需求,行业中常见的方案是…

如何在CentOS搭建docker compose ui可视化工具并无公网IP远程管理容器

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

【C++ leetcode】双指针问题(续)

3. 202 .快乐数 题目 编写一个算法来判断一个数 n 是不是快乐数。 「快乐数」 定义为: 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。如果这个过程 结…

node.js快速入门-day03

个人名片: 😊作者简介:一名大二在校生 🤡 个人主页:坠入暮云间x 🐼座右铭:给自己一个梦想,给世界一个惊喜。 🎅**学习目标: 坚持每一次的学习打卡 文章目录 web服务器创建…

JavaScript高级(十三)---ES6中Set,map

ES6 Set 在ES6之前,我们存储数据的结构主要有两种:数组、对象。 在ES6中新增了另外两种数据结构:Set、Map,以及它们的另外形式WeakSet、WeakMap。 Set是一个新增的数据结构,可以用来保存数据,类似于数组&a…

[隐私计算实训营学习笔记] 第1讲 数据要素流通

信任四基石 数据的分级分类 技术信任:全链路审计、闭环完成的数据可信流通体系 技术信任:开启数据密态时代 数据可流通的基础设施:密态天空计算

供需平衡对电子元器件价格的影响

随着科技的迅猛发展和智能化产品的普及,电子元器件已经成为现代社会不可或缺的一部分。从手机到汽车,从家用电器到工业机械,无处不在的电子元器件都在支撑着我们的生活和工作。然而,电子元器件市场的供需平衡却经常面临挑战&#…

flask+ flask_socketio HTTP/1.1“ 400 公网IP 问题解决方案

很经典的一个跨域问题 在服务端改成socketio SocketIO(app, cors_allowed_origins"*")就可以了

杰发科技AC7801——Keil编译的Hex大小如何计算

编译结果是Keil里面前三个数据的总和: 即CodeRoDataRWData的总和。 通过ATCLinkTool工具查看内存,发现最后一个字节正好是5328 注意读内存数据时候需要强转成32位,加1000的 增加1024的地址只需要加256即可

[蓝桥杯 2019 省 A] 外卖店优先级

模拟 双指针 #include<iostream> #include<algorithm> using namespace std; using ll long long; #define int long long const int N 1e510; const int inf 0x3f3f3f3f; const int mod 1e97;int n,m,ts;bool vis[N]; int a[N]; int last[N]; pair<int,int…