抽象类
Java中abstract是抽象的意思,可以修饰类、成员方法。
abstract修饰类,这个类就是抽象类;修饰方法,这个方法就是抽象方法。
抽象方法只有方法签名,不能声明方法体。
一个类中如果定义了抽象方法,这个类必须声明成抽象类,否则报错。
抽象类可以理解成不完整的设计图,一般作为父类,让子类来继承。
当父类知道子类一定要完成某些行为,但是每个子类该行为的实现又不同,于是该父类就把该行为定义成抽象方法的形式,具体实现交给子类去完成。此时这个类就可以声明成抽象类。
类有的成员(成员变量、方法、构造器)抽象类都具备
抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类
一个类继承了抽象类必须重写完抽象类的全部抽象方法,否则这个类也必须定义成抽象类。
不能用abstract修饰变量、代码块、构造器。
最重要的特征:得到了抽象方法,失去了创建对象的能力(有得有失)
系统需求
某加油站推出了2种支付卡,一种是预存10000的金卡,后续加油享受8折优惠,另一种是预存5000的银卡 ,后续加油享受8.5折优惠。
请分别实现2种卡片进入收银系统后的逻辑,卡片需要包含主人名称,余额,支付功能。
分析实现
创建一张卡片父类:定义属性包括主人名称、余额、支付功能(具体实现交给子类)
创建一张白金卡类:重写支付功能,按照原价的8折计算输出。
创建一张银卡类:重写支付功能,按照原价的8.5折计算输出。
模板方法
使用场景说明:当系统中出现同一个功能多处在开发,而该功能中大部分代码是一样的,只有其中部分可能不同的时候。
模板方法模式实现步骤
1、定义一个抽象类。2、定义2个方法,一个是模板方法:把相同代码放里面去,不同代码定义成抽象方法
3、子类继承抽象类,重写抽象方法。
现在有两类学生,一类是中学生,一类是小学生,他们都要写《我的爸爸》这篇作文。
要求每种类型的学生,标题第一段和最后一段,内容必须一样。正文部分自己发挥。
请选择最优的面向对象方案进行设计。
package com.itheima.d9_abstract_template; public abstract class Student { /** 正式:声明了模板方法模式 final :这个方法不能被子类重写,因为它是给子类直接使用的。 */ public final void write(){ System.out.println("\t\t\t\t《我的爸爸》"); System.out.println("你的爸爸是啥样,来说说:"); // 正文部分(每个子类都要写的,每个子类写的情况不一样 // 因此。模板方法把正文部分定义成抽象方法,交给 // 具体的子类来完成) System.out.println(writeMain()); System.out.println("我的爸爸简直太好了~~"); } public abstract String writeMain(); }
package com.itheima.d9_abstract_template; public class StudentChild extends Student{ @Override public String writeMain() { return "的爸爸太牛b了,他总是买东西给我吃。。"; } }
package com.itheima.d9_abstract_template; public class StudentMiddle extends Student{ @Override public String writeMain() { return "我的爸爸也很牛,我开车都不看红绿灯的," + "下辈子还要做他儿子~~"; } }
模板方法我们是建议使用final修饰的,这样会更专业,那么为什么呢?
模板方法是给子类直接使用的,不是让子类重写的,
一旦子类重写了模板方法,则模板方法就失效了,因此,加上final后可以防止子类重写了模板方法,这样更安全、专业。
模板方法模式解决了什么问题?
提高了代码的复用性
模板方法已经定义了通用结构,模板方法不能确定的部分定义成抽象方法,交给子类实现,因此,使用者只需要关心自己需要实现的功能即可。