当前位置: 首页 > news >正文

【Java SE】抽象类/方法、模板设计模式

目录

1.抽象类/方法

1.1 基本介绍

1.2 语法格式

1.3 使用细节

2. 模板设计模式(抽象类使用场景)

2.1 基本介绍

2.2 具体例子


1.抽象类/方法

1.1 基本介绍

① 当父类的某些方法,需要声明,但是又不确定如何实现时,可以将其声明为抽象方法

② 类中只要存在一个抽象方法,则该类必须为抽象类

 抽象类的价值更多作用在于设计,具体来说:设计者设计好后,让子类继承并实现父类的抽象方法

public class Test {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.eat();
    }
}

//抽象类
abstract class Animal{
    //抽象方法,只知道吃的动作,但不知道具体的动物吃什么东西
    public abstract void eat();
}

class Dog extends Animal{
    public void eat(){
        System.out.println("狗吃骨头");
    }
}

1.2 语法格式

  • 抽象类:被 abstract 修饰的类,一般会被继承,由其子类来实现抽象的方法

[修饰符] abstract class 类名{
    
}
  • 抽象方法:被 abstract 修饰而且没有方法体的方法,也叫做没有实现的方法

[修饰符] abstract 返回值类型 方法名([形参列表]);//不需要方法体{}

1.3 使用细节

① abstract 只能修饰类和方法,不能用来修饰属性和其他的

 使用 abstract 修饰类,只是表示该类为抽象类,类内部的属性和方法不会自动具有 abstract 修饰符

 抽象类不能创建对象实例

 抽象类的本质还是类,可以有类的各种成员。比如:非抽象方法、构造器、非静态方法/属性、静态方法/属性等等,都可以继承给子类

public class Test {
    public static void main(String[] args) {
        Dog dog = new Dog();
        System.out.println(Dog.num);
        System.out.println(dog.name);
        dog.eat();
    }
}

//抽象类
abstract class Animal{
    public static int num = 1;
    public String name = "小马";
    public abstract void eat();//抽象方法
}

class Dog extends Animal{

    //实现父类的抽象方法
    public void eat(){
        System.out.println("狗吃骨头");
    }
}
/*输出结果
1
小马
狗吃骨头
 */

⑤ 如果一个类继承了抽象类,则它必须实现抽象类的所有抽象方法,除非它自己也声明为 abstract类,否则编译不通过

 ⑥ 抽象方法不能使用 private、final、static 来修饰,因为这些关键字都是和重写相违背的

        private:如果父类的抽象方法用 private 修饰,那其子类没有访问权限,无法实现抽象方法

        final:如果父类的抽象方法用 final 修饰,则该方法不能重写,其子类无法实现抽象方法

        static:static 修饰的方法可以 "直接类.方法名" 调用,而 abstract 修饰的方法没有方法体,因此两者是相悖的【这样理解不知道对不对】

2. 模板设计模式(抽象类使用场景)

2.1 基本介绍

抽象类体现的就是一种模板模式的设计,抽象类作为多个子类的通用模板,子类在抽象类的基础上进行扩展、改造,但子类总体上会保留抽象类的行为方式

解决的问题

 当功能内部一部分实现是确定的,另一部分实现是不确定的,这时可以把不确定的部分暴露出去,让子类去实现

 换句话说,在软件开发中实现一个算法时,整体步骤很固定、通用,这些步骤已经在父类中写好了。但是某些部分易变,则易变部分可以抽象出来,供不同子类实现。这就是一种模板模式

看上面的文字可能会觉得很抽象,可以结合具体的例子理解一下

2.2 具体例子

需求:计算不同类各自任务的执行时间

未使用模板设计模式之前

public class demo {
    public static void main(String[] args) {
        new JobA().job();
        new JobB().job();
    }
}

class JobA{
    public void job(){
        int result = 0;
        long startTime = System.currentTimeMillis();//开始时间
        for(int i=0;i<100000;i++){
            result += i;
        }
        long endTime = System.currentTimeMillis();//结束时间
        long duration = endTime - startTime;
        System.out.println("任务执行时间: " + duration + "毫秒");
    }
}

class JobB{
    public void job(){
        int result = 1;
        long startTime = System.currentTimeMillis();//开始时间
        for(int i=0;i<8000;i++){
            result *= i;
        }
        long endTime = System.currentTimeMillis();//结束时间
        long duration = endTime - startTime;
        System.out.println("任务执行时间: " + duration + "毫秒");
    }
}

缺点:代码冗余,复用性差,可以看到代码整体的步骤是很固定的,如下:

①  记录任务开始时间

②  执行任务

③  记录任务结束时间

④  打印任务执行时间

其中,① ③ ④ 是固定不变的,变的只有 ② ,这就有了改进的空间

引入模板设计模式

优点:利用抽象类+动态绑定机制使得模板类中的 job() 可以动态调用执行方法,代码复用性高  

public class demo {
    public static void main(String[] args) {
        new JobA().calculateJobTime();
        new JobB().calculateJobTime();
    }
}

//模板类
abstract class Template{
    public abstract void job();//抽象方法
    //计算任务执行时间
    public void calculateJobTime(){
        long startTime = System.currentTimeMillis();//开始时间
        job();//动态绑定机制
        long endTime = System.currentTimeMillis();//结束时间
        long duration = endTime - startTime;
        System.out.println("任务执行时间: " + duration + "毫秒");
    }
}

class JobA extends Template{
    //重写抽象方法
    public void job(){
        int result = 0;
        for(int i=0;i<100000;i++){
            result += i;
        }
    }
}

class JobB extends Template{
    //重写抽象方法
    public void job(){
        int result = 1;
        for(int i=0;i<8000;i++){
            result *= i;
        }
    }
}

相关文章:

  • 【递归,搜索与回溯算法篇】- 名词解释
  • 从X光片生成合成计算机断层扫描(CT)样成像的策略:一项范围审查|文献速递-医学影像人工智能进展
  • 【C++】sort函数的两种用法
  • 分布式容器技术是什么
  • 解决python配置文件类configparser.ConfigParser,插入、读取数据,自动转为小写的问题
  • AGI成立的条件
  • 算法及数据结构系列 - 回溯算法
  • 嵌入式芯片与系统设计竞赛,值得参加吗?如何选题?需要学什么?怎么准备?
  • QT开发(4)--各种方式实现HelloWorld
  • centos 7 搭建FTP user-list用户列表
  • LeetCode算法题(Go语言实现)_07
  • ensp 公司组网拓扑图
  • 如何给商品一键换色?图生生AI,告别繁琐修图
  • html5炫酷3D立体文字效果实现详解
  • 基于PySide6的CATIA自动化工具开发实战——空几何体批量清理系统
  • GITLAB部署安装教程
  • Kubernetes Init 容器:实现 Nginx 和 PHP 对 MySQL 的依赖检查
  • 9-类、结构体、指针、引用
  • 挖矿病毒应急响应处置手册
  • 嵌入式Linux——Framebuffer应用编程
  • 巴基斯坦总理:希望通过和平对话方式解决与印方问题
  • 上海劳模风采馆焕新升级后重新开放,展示480位劳模先进故事
  • 聆听百年唐调正声:唐文治王蘧常吟诵传习的背后
  • 丹麦召见美外交官,强调“不能容忍”美在格陵兰岛间谍活动
  • 菲护卫艇企图侵闯中国黄岩岛领海,南部战区:依法依规跟踪监视、警告驱离
  • 央视315晚会曝光“保水虾仁”后,湛江4家涉事企业被罚超800万元