从模板方法模式深入理解Java抽象类
来源:互联网 发布:淘宝网上传图片尺寸 编辑:程序博客网 时间:2024/06/14 10:09
二话不说先上代码,如下所示为一个抽象类(抽象汽车模型)与它的两个具体实现类(宝马模型、奔驰模型)的模拟程序:
/* * 抽象模板类,抽象汽车模型 */public abstract class AbstractCarModel {//汽车要能启动!<span style="white-space:pre"></span>protected abstract void start();<span style="white-space:pre"></span>//汽车要能刹车!protected abstract void stop();//汽车要能响喇叭!protected void alarm(){//一般汽车喇叭都是“滴滴滴”哦,要想“巴拉拉”或者“啪啪啪”去实现类自己重写去!System.out.println("滴滴滴滴滴滴");}//最重要的是,汽车要能行驶!而且行驶流程是固定的,不能改变!protected final void run(){//启动this.start();//鸣笛this.alarm();//到达目的地就停车this.stop();}}
/* * 具体实现类,宝马汽车模型 */public class BMWModel extends AbstractCarModel{//实现汽车抽象模板类的start()方法,使宝马能够启动@Overrideprotected void start() {System.out.println("宝马启动!");}//实现汽车抽象模板类stop()方法,使宝马能够刹车@Overrideprotected void stop() {System.out.println("宝马停车!");}//宝马汽车喇叭响声就是“滴滴滴”,继承父类alarm()方法即可//所有汽车的行驶流程都是一致的,继承父类run()方法}
/* *具体实现类,奔驰汽车模型 */public class BENZModel extends AbstractCarModel{//实现汽车抽象模板类的start()方法,使奔驰能够启动@Overrideprotected void start() {System.out.println("奔驰启动!");}//实现汽车抽象模板类stop()方法,使奔驰能够刹车@Overrideprotected void stop() {System.out.println("奔驰停车!");}//奔驰汽车喇叭响声就是“巴拉巴拉巴拉”,需要重写父类alarm()方法@Overrideprotected void alarm(){System.out.println("巴拉巴拉巴拉");}//所有汽车的行驶流程都是一致的,继承父类run()方法}
/* * 实现场景类 */public class Client {public static void main(String[] args){//做个宝马BMWModel bmw = new BMWModel();//开辆奔驰BENZModel benz = new BENZModel();//宝马跑一跑bmw.run();System.out.println("*************分割线*************");//奔驰跑一跑benz.run();}}
2、我们知道,不合理使用类的继承会破坏父类封装性(子类可能篡改父类实现),所以抽象类的正确使用姿势是:封装不变部分,扩展可变部分。如上例中,run()方法是被AbstractCarModel抽象类用final关键字封装好的,不允许篡改。而start()方法、stop()方法与alarm()方法都是可变的,子类去实现或者重写,合理地实现了扩展。
3、这其实就是一个简单的模板方法模式的体现,我在阿里巴巴面试的时候被问到:用接口不能实现,非抽象类实现不可的应用场景?我这时候就该回答模板方法设计模式~~~~(>_<)~~~~
下面详细介绍模板方法模式
模板方法模式的重点在于抽象模板类的方法类型,主要分三种:
1、抽象方法:由抽象类声明,用abstract关键字标识,由具体实现类去实现。如上例所示的start()方法与stop()方法。
2、具体方法:由抽象类声明并实现,用final关键字标识,在具体实现类中只能调用。如上例所示的run()方法。
3、钩子方法:由抽象类声明并实现,具体实现类可以继承抽象父类的默认实现,也可以根据具体情况进行修改扩展。如上例所示的alarm()方法,BMWModle类就是继承了AbstractCarModel抽象类alarm()方法的默认实现;而BENZModel类就是重写了alarm()方法。
HttpServlet中的钩子方法:
钩子方法经常是一个空的实现,因为一个实现类并不需要全部的方法,比如HttpServlet类中的doPost()、doGet()、doPut()、doDelete()、doHead()……为处理HTTP请求,每一种HTTP方法对应着一个do方法,这也是钩子方法默认的命名规则。这些方法在HttpServlet抽象类中都是以空实现的钩子方法存在的。在具体实现的时候,一般一个Servlet只需要处理某几个HTTP方法,在具体的servlet中就重写对应的几个do方法就可以了。
钩子方法和具体方法的存在使抽象类与接口具有了最主要的差异:
接口主要体现的是一种规范,实现接口的类只能去实现这种规范,但用户通过与统一接口对接实现了规范与实现的分离,极大地降低了模块间的耦合度;
而通过模板方法模式使用抽象类,可以继承某些具体方法,实现了规范并增加了代码的可重用性,而继承抽象方法与钩子方法使实现类可以灵活地扩展抽象模板类,接口并不能有这样的灵活扩展特性,是非常常用而有意义的一种设计模式!
- 从模板方法模式深入理解Java抽象类
- 从抽象类到模板方法模式
- 【设计模式】深入理解Java的接口和抽象类
- 深入理解Java接口和抽象类
- 深入理解java接口和抽象类
- 深入理解java接口和抽象类
- 深入理解java接口和抽象类
- JAVA模板方法设计模式(从现实生活角度理解代码原理)
- Java设计模式——模板方法设计模式——抽象类的运用
- Java笔记2 面向对象<3>final关键字、抽象类、模板方法模式、接口
- 黑马程序员—Java面向对象(抽象类、模板方法设计模式、接口、多态、内部类)
- 别样JAVA学习(五)继承上(0.1)抽象类和模板方法模式
- java 深入理解Java的接口和抽象类
- java 深入理解Java的接口和抽象类
- java:深入理解Java的接口和抽象类
- Java基础:深入理解Java的接口和抽象类
- 抽象类的深入理解
- 理解 Delphi 的类(十一) - 深入类中的方法[8] - 抽象方法与抽象类
- ”无法启动此程序,因为计算机中丢失LIBEAY32.DLL“ 问题解决办法
- JVM内存组成及分配 (转)
- linux常用命令(个人版)
- 函数是直线的充要条件是二阶导数为0_20160517
- 最快的Android模拟器 --- Genymotion安装使用
- 从模板方法模式深入理解Java抽象类
- 如何在Ubuntu 14.04中安装最新版Eclipse
- 1016. Phone Bills (25)
- 证明多元函数可导,但不连续_20160519
- 数据库函数
- 多元隐函数三种求偏导方法_20160521
- 访问修饰符 :public: internal:protected: private:
- eclipse创建maven项目
- HELLO---MVC