2.4 Java之抽象类与模板方法设计模式
Abstract关键字
举例
抽象类vehicle,没必要创建实例,方法也没必要具体说明,给个方法声明就好了
子类卡车,汽车继承,去创建实例,调用它们各自具体的方法
抽象类和抽象方法
重点:
- 非抽象子类一定要重写所有的抽象方法
- 抽象方法所在类必定为抽象类
- 抽象方法,如public abstract void eat();//没有大括号
-
抽象类为什么有构造器:
类的实例化过程,最终一定会调用Object的构造器,父类有可能是抽象的,所以抽象类的构造器要保留
背景:
- worker没有重写eat(),只能继承父类抽象类的eat()方法,
- 父类的eat()被注释
- 抽象方法只保留功能,没有具体方法内容,但要书写抽象方法声明,
不然编译期不通过(看左边),如图所示,Person没有eat方法,调用不了
- 抽象类可以有非抽象方法
如getName()方法
多态性
创建的不是Person类对象,实体是Worker对象,但虚拟方法调用,即抽象类和方法不影响多态性
若多层继承,则子类若要为所有父类,父类的父类抽象方法重写,否则只能为抽象类
抽象父类walk方法没有重写,子类只能声明为抽象类,所以报错
空方法不是抽象方法
Abstract练习1
抽象父类
管理人员类(子类)
工人类(子类)
测试类
虚拟方法调用,抽象类不影响多态性
Abstract练习2
日期类
父类
- 默认创建的方法体内为birthday(等价于birthday.toString())改为birthday.toDateString()
子类1
子类2
- 关注toString()方法写法,要调用父类的toString()方法
测试类
- Ctrl+shift+O :导包
- 最后一行代码:打印对象引用,则自动调用toString()方法
运行结果
- 直接输出加100,因为是小时结算工资,没意义
Abstract关键字的限制
为什么不能修饰属性,构造器,private,final,static?
- 虚拟方法调用不适用于属性,即子类没法覆盖父类属性,则覆盖无意义
- 构造器不能重写,无法覆盖
- 子类不能覆盖父类声明为private的方法,不认为是重写,即private方法子类不能重写
- final要求不能重写,矛盾
- 没有方法体,残缺的方法,调用为空,没有意义
知识串联
回顾几何图形类,修改为抽象类(泛泛概念,不需创建实例)
–
模板方法设计模式
code()= this.code()
code()虚拟方法调用,编译时认为是父类的code方法,运行时实际是子类code方法
继承模板抽象类,重写抽象方法(子类一定要重写,不然就是抽象类)
就能计算时间