我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Java 抽象类与模板设计模式详解

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Java 抽象类与模板设计模式详解

抽象类

抽象类是为了方法覆写而提供的类结构,因为其无法自身直接进行对象实例化操作,所以在实际应用中,抽象类主要目的是进行过程操作使用,当你要使用抽象类进行开发的时候,往往都是在你设计中需要解决类继承问题时所带来的的代码重复处理。

普通类是一个完善的功能类,可以直接产生实例化对象,并且在普通类中可以包含有构造方法、普通方法、static方法、常量和变量等内容。而抽象类是指在普通类的结构里面增加抽象方法的组成部分。

在这里小编建了一个前端学习交流扣扣群:132667127,我自己整理的最新的前端资料和高级开发教程,如果有想需要的,可以加群一起学习交流

那么什么叫抽象方法呢?所有的普通方法上面都会有一个“{}”,这个表示方法体,有方法体的方法一定可以被对象直接使用。而抽象方法,是指没有方法体的方法,同时抽象方法还必须使用关键字abstract做修饰。而拥有抽象方法的类就是抽象类,抽象类要使用abstract关键字声明。

抽象类已经实现的方法是为了代码复用,待实现的方法是为了限制子类的功能。

定义一个抽象类

    
 abstract class AbstractMessage{
       
     private String infoString ;    
     
     public AbstractMessage(String info) {
         this.infoString = info;
     }
         
     public String getInfo() {
         return this.infoString;
     }
     
     public abstract void send() ;
 }

使用抽象类

首先,我们直接实例化抽象类的对象,看下是否可以直接进行实例化抽象类,代码示例如下。

 abstract class AbstractMessage{
     
     private String infoString ;
     
     public AbstractMessage(String info) {
         this.infoString = info;
     }
     
     public String getInfo() {
         return this.infoString;
     }
     
     public abstract void send() ;
 }
 public class Students {
     public static void main(String[] args) {
         System.out.println();
         AbstractMessage messageInfo = new AbstractMessage("芝兰生于深谷,不以无人而不芳\r\n" + "君子修身养德,不以穷困而改志") ;
         messageInfo.send();
     }
 }

运行上述代码,通过如下结果可知,AbstractMessage抽象类是无法直接进行实例化操作。

 Error:(21, 39) java: abstractMessage是抽象的; 无法实例化

那么为什么无法被直接实例化呢,试想当一个类实例化之后,那么可以通过对象调用类的属性或方法,但由于抽象方法并没有方法体,因此无法进行调用。既然无法进行方法调用的话,又怎么去产生实例化对象呢。

抽象类的使用约束:

  1. 抽象类不能直接实例化,抽象类必须有子类,使用extends继承,一个子类只能继承一个抽象类,需要依靠子类采用向上转型的方式处理;
  2. 抽象方法必须为public或者protected,因为如果为private,则不能被子类继承,子类便无法实现该方法,当缺省情况下默认为public;
  3. 子类(不是抽象类)必须覆写抽象类之中的全部抽象方法;

代码示例如下:

 public class Lian {
     public static void main(String[] args) {
         System.out.println();
         
         AbstractMessage messageInfo = new message("芝兰生于深谷,不以无人而不芳\r\n" + "君子修身养德,不以穷困而改志") ;
         messageInfo.send();
     }
 }
 
 abstract class AbstractMessage{
     
     private String infoString ;
     
     public AbstractMessage(String info) {
         this.infoString = info;
     }
     
     public String getInfo() {
         return this.infoString;
     }
     
     public abstract void send() ;
 }
 
 
 class message extends AbstractMessage {
     public message(String info) {
         super(info); //抽象类存在有参构造方法,子类必须明确调用有参构造。
     }
     
     @Override
     public void send() {
         System.out.println("发送信息\n"+super.getInfo());
     }
 }

运行结果如下:

 发送信息
 芝兰生于深谷,不以无人而不芳
 君子修身养德,不以穷困而改志

通过如上运行结果,可以发现:

  1. 继承抽象类的子类必须覆写抽象方法,而继承普通类的子类可以选择性的覆写其中方法;
  2. 抽象类较普通类而言,多了抽象方法,其他组成部分和普通类一样,普通类对象可以直接进行实例化,但抽象类的对象必须通过子类向上转型进行实例化。

抽象类中允许有构造方法?

由于抽象类里会存在一些属性,那么抽象类中一定存在构造方法,其存在目的是为了属性的初始化。 并且子类对象实例化的时候,依然满足先执行父类构造,再执行子类构造的顺序。

范例如下:

 public class Lian {
     public static void main(String[] args) {
         System.out.println();
         
         AbstractMessage messageInfo = new message("芝兰生于深谷,不以无人而不芳\r\n" + "君子修身养德,不以穷困而改志") ;
         messageInfo.send();
     }
 }
 
 abstract class AbstractMessage{
     
     private String infoString ;
     
     public AbstractMessage(String info) {
         this.infoString = info;
         System.out.println("abstractMessage 构造方法");
     }
     
     public String getInfo() {
         return this.infoString;
     }
 
     
     public abstract void send() ;
 }
 
 
 class message extends AbstractMessage {
     
     public message(String info) {
         super(info);
         System.out.println("message 构造方法");
     }
 
     
     @Override
     public void send() {
         System.out.println("发送信息\n"+super.getInfo());
     }
 }

执行结果:

 abstractMessage 构造方法
 message 构造方法
 发送信息
 芝兰生于深谷,不以无人而不芳
 君子修身养德,不以穷困而改志

抽象类允许使用final声明?

因为抽象类必须有子类,而final定义的类不能有子类,因此抽象类运行不能final声明。

抽象类允许使用static声明?

如下一个外部抽象类的示例:

 public class Lian {
     public static void main(String[] args) {
         System.out.println();
         
         AbstractMessage messageInfo = new message("芝兰生于深谷,不以无人而不芳\r\n" + "君子修身养德,不以穷困而改志") ;
         messageInfo.send();
     }
 }
 
 static  abstract class AbstractMessage{
     
     private String infoString ;
 
     
     public AbstractMessage(String info) {
         this.infoString = info;
         System.out.println("abstractMessage 构造方法");
     }
     
     public String getInfo() {
         return this.infoString;
     }
     
     public abstract void send() ;
 }
 
 
 class message extends abstractMessage {
     
     public message(String info) {
         super(info);
         System.out.println("message 构造方法");
     }
     
     @Override
     public void send() {
         System.out.println("发送信息\n"+super.getInfo());
     }
 }
 Error:(12, 18) java: 此处不允许使用修饰符static

再看一个关于内部抽象类:

 public class Lain {
     public static void main(String[] args) {
         System.out.println();
         
         AbstractMessage.AbstractMessageChild messageInfo = new message("芝兰生于深谷,不以无人而不芳\r\n" + "君子修身养德,不以穷困而改志") ;
         messageInfo.send();
     }
 }
 
 abstract class AbstractMessage{
     static abstract class AbstractMessageChild{//static定义的内部类属于外部类
         
         private String infoString ;
         
         public AbstractMessageChild(String info) {
             this.infoString = info;
             System.out.println("abstractMessageChild 构造方法");
         }
         
         public String getInfo() {
             return this.infoString;
         }
         
         public abstract void send() ;
     }
 }
 
 
 class message extends AbstractMessage.AbstractMessageChild {
     
     public message(String info) {
         super(info);
         System.out.println("message 构造方法");
     }
 
     
     @Override
     public void send() {
         System.out.println("发送信息\n"+super.getInfo());
     }
 }

执行结果如下:

 abstractMessageChild 构造方法
 message 构造方法
 发送信息
 芝兰生于深谷,不以无人而不芳
 君子修身养德,不以穷困而改志

由此可见,外部抽象类不允许使用static声明,而内部的抽象类运行使用static声明。使用static声明的内部抽象类相当于一个外部抽象类,继承的时候使用“外部类.内部类”的形式表示类名称。

可以直接调用抽象类中用static声明的方法么? 任何时候,如果要执行类中的static方法的时候,都可以在没有对象的情况下直接调用,对于抽象类也一样。 范例如下:

 public class Lain {
     public static void main(String[] args) {      
         abstractMessage.getInfo();
     }
 }

 abstract class AbstractMessage{
     
     public static void getInfo() {
         System.out.println("芝兰生于深谷,不以无人而不芳\r\n君子修身养德,不以穷困而改志");
     }
     
     public abstract void send() ;
 }
 
 
 class message extends AbstractMessage {
     
     @Override
     public void send() {
         System.out.println("发送信息\n");
     }
 }

运行结果:

 芝兰生于深谷,不以无人而不芳
 君子修身养德,不以穷困而改志

(5)有时候由于抽象类中只需要一个特定的系统子类操作,所以可以忽略掉外部子类。这样的设计在系统类库中会比较常见,目的是对用户隐藏不需要知道的子类。 范例如下:

 public class Lain {
     public static void main(String[] args) {
         AbstractMessage abstractMessage = AbstractMessage.getInstance();
         abstractMessage.send();
     }
 }
 
 abstract class AbstractMessage{
     
     public abstract void send() ;
     
     public static void getInfo() {
         System.out.println("芝兰生于深谷,不以无人而不芳\r\n君子修身养德,不以穷困而改志");
     }
     
     private static class AbstractMessageChild extends AbstractMessage{//内部抽象类子类
         public void send(){//覆写抽象类的方法
             System.out.println("发送信息 !");
         }
     }
 
     
     public static AbstractMessage getInstance(){
         return new AbstractMessageChild();
     }
 }
 
 

运行结果:

 发送信息 !

抽象类之模板设计模式

模板方法模式:在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。模板方法模式是基于继承的代码复用基本技术,模板方法模式的结构和用法也是面向对象设计的核心之一。在模板方法模式中,可以将相同的代码放在父类中,而将不同的方法实现放在不同的子类中。

在模板方法模式中,我们需要准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式实现,然后声明一些抽象方法来让子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现,这就是模板方法模式的用意。模板方法模式体现了面向对象的诸多重要思想,是一种使用频率较高的模式。

例如,现在有如下三类事务:

  • 机器人:充电、工作;
  • 人:吃饭、工作、睡觉;
  • 猪:吃饭、睡觉;

现要求实现一个程序, 通过抽象类定义并实现一个模板方法。这个模板方法定义了算法的骨架,而逻辑的组成步骤在相应的抽象操作中,推迟到子类去实现可以实现三种不同事物的行为。

 abstract class AbstractAction{
 
     public static final int EAT = 1 ;
     public static final int SLEEP = 3 ;
     public static final int WORK = 5 ;
 
     public abstract void eat();
     public abstract void sleep();
     public abstract void work();
 
     public void commond(int flags){
         switch(flags){
             case EAT:
                 this.eat();
                 break;
             case SLEEP:
                 this.sleep();
                 break;
             case WORK:
                 this.work();
                 break;
             default:
                 break;
         }
     }
 }

定义一个机器人的类,如下:

 class Robot extends AbstractAction{
 
     @Override
     public void eat() {
         System.out.println("机器人充电");
     }
 
     @Override
     public void sleep() {
     }
 
     @Override
     public void work() {
         System.out.println("机器人工作");
     }
 
 }
 

定义一个人的类,如下:

 class Person extends AbstractAction{
 
     @Override
     public void eat() {
         System.out.println("人吃饭");
     }
 
     @Override
     public void sleep() {
         System.out.println("人睡觉");
     }
 
     @Override
     public void work() {
         System.out.println("人工作");
     }
 
 }

定义一个猪的类,如下:

 class Pig extends AbstractAction{
 
     @Override
     public void eat() {
         System.out.println("猪吃饭");
     }
 
     @Override
     public void sleep() {
         System.out.println("猪睡觉");
     }
 
     @Override
     public void work() {
     }
 
 }
 

主类如下:

 public class Students {
     public static void main(String[] args) {
         run(new Robot());
         run(new Person());
         run(new Pig());
     }
     public static void run(AbstractAction abstractAction){
         abstractAction.commond(AbstractAction.EAT);
         abstractAction.commond(AbstractAction.SLEEP);
         abstractAction.commond(AbstractAction.WORK);
     }
 
 }
 

运行结果:

 机器人充电
 机器人工作
 人吃饭
 人睡觉
 人工作
 猪吃饭
 猪睡觉

所有的子类如果要想正常的完成操作,必须按照指定的方法进行覆写才可以,而这个时候抽象类所起的功能就是一个类定义模板的功能。

模板设计模式的优缺点

模板方法模式通过把不变的行为搬移到超类,去除了子类中的重复代码。子类实现算法的某些细节,有助于算法的扩展。通过一个父类调用子类实现的操作,通过子类扩展增加新的行为,符合“开放-封闭原则”。 2.)缺点 每个不同的实现都需要定义一个子类,这会导致类的个数的增加,设计更加抽象。 3.)适用场景 在某些类的算法中,用了相同的方法,造成代码的重复。控制子类扩展,子类必须遵守算法规则。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Java 抽象类与模板设计模式详解

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Java 抽象类与模板设计模式详解

抽象类抽象类是为了方法覆写而提供的类结构,因为其无法自身直接进行对象实例化操作,所以在实际应用中,抽象类主要目的是进行过程操作使用,当你要使用抽象类进行开发的时候,往往都是在你设计中需要解决类继承问题时所带来的的代码重复处理。普通类是一个完
2023-06-03

Golang设计模式中抽象工厂模式详细讲解

抽象工厂模式用于生成产品族的工厂,所生成的对象是有关联的。如果抽象工厂退化成生成的对象无关联则成为工厂函数模式。比如本例子中使用RDB和XML存储订单信息,抽象工厂分别能生成相关的主订单信息和订单详情信息
2023-01-11

怎么理解Java设计模式的抽象工厂模式

这篇文章主要讲解了“怎么理解Java设计模式的抽象工厂模式”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么理解Java设计模式的抽象工厂模式”吧!一、什么是抽象工厂模式为创建一组相关或相互
2023-06-25

Java设计模式之模板方法模式TemplateMethodPattern详解

在我们实际开发中,如果一个方法极其复杂时,如果我们将所有的逻辑写在一个方法中,那维护起来就很困难,要替换某些步骤时都要重新写,这样代码的扩展性就很差,当遇到这种情况就要考虑今天的主角——模板方法模式
2022-11-13

Python设计模式之抽象工厂模式

python面向对象编程入门,我们需要不断学习进步 """抽象工厂模式的实现"""import randomclass PetShop:"""宠物商店"""def __init__(self, animal_factory=None):""
2022-06-04

java设计模式之抽像工厂详解

一、概念  提供一个创建一系列相关或相互依赖对像的接口,而无需指定它们具体的类。二、模式动机  这一系列对像之间是相互依赖的,相当于一个产品族 三、模式的结构通过上图我们可以清楚的看到抽像工厂模式包括以下4个角色:  1.抽像工厂角色(A
2023-05-31

Java设计模式-模板方法模式

定义Define the skeleton of an algorithm in an operation,deferring some steps to subclasses.Template Method lets subclasses
2023-06-05

举例讲解Python设计模式编程的代理模式与抽象工厂模式

代理模式 Proxy模式是一种常用的设计模式,它主要用来通过一个对象(比如B)给一个对象(比如A) 提供'代理'的方式方式访问。比如一个对象不方便直接引用,代理就在这个对象和访问者之间做了中介 你先设想:一个对象提供rgb三种颜色值,我想获
2022-06-04

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录