文章目录
抽象类在前期学习时可能不太懂它的使用场景,我们尽可能的关注它的语法。
抽象类
●在Java中abstract是抽象的意思,可以修饰类、成员方法。
●abstract修饰类,这个类就是抽象类;修饰方法,这个方法就是抽象方法。
注意事项
抽象方法只有方法签名,不能声明方法体。
一个类中如果定义了抽象方法,这个类必须声明成抽象类,否则报错。
使用场景
-
抽象类可以理解成不完整的设计图,一般作为父类, 让子类来继承。
-
当父类知道子类-定要完成某些行为,但是每个子类该行为的实现又不同,于是该父类就把该行为定义成抽象方法的形式,具体实现交给子类去完成。此时这个类就可以声明成抽象类。
代码演示
ALT+ENTER 可以快捷调出代码重写提示
package com.abstract_;
public abstract class Abstract_ {
public abstract void baka();
}
package com.abstract_;
public class boy_girl extends Abstract_{
@Override
public void baka() {
System.out.println("大笨蛋你在里面吗");
}
}
package com.abstract_;
public class Imnot extends Abstract_{
@Override
public void baka() {
System.out.println("大笨蛋不在里面");
}
}
package com.abstract_;
public class Main {
public static void main(String[] args) {
boy_girl bg = new boy_girl();
bg.baka();
Imnot in = new Imnot();
in.baka();
}
}
运行结果:
大笨蛋你在里面吗
大笨蛋不在里面
通过上面的代码我们应该可以看出: 抽象类和抽象方法本身在定义时并不具有什么样的功能,抽象类和方法靠子类的重写来获得全新的技能
Of course: 抽象类的里面也是可以定义一些数据和方法的,更能提高代码的灵活性和复用性
继承抽象类有哪些要注意?
- 个类如果继承了抽象类,那么这个类必须重写完抽象类的全部抽象方法,
否则这个类也必须定义成抽象类。
抽象类的应用案例
系统需求
某加油站推出了2种支付卡,一种是预存10000的金卡,后续加油享受8折优惠,另い种
是预存5000的银卡后续加油享受8.5折优惠。
请分别实现2种卡片进入收银系统后的逻辑,卡片需要包含主人名称,余额,支付功能。
分析实现
创建一张卡片父类:定义属性包括主人名称、余额、支付功能(具体实现交给子类)
创建一张白金卡类:重写支付功能,按照原价的8折计算输出。
创建一张银卡类:重写支付功能,按照原价的8.5折计算输出。
接下来我们主要简单演示一下,并不把所有功能都实现,注重学习如何使用抽象类。
package com.AnLi_gas_station;
public abstract class Card {
private String owner;
private int balance;
public abstract void pay(int price,int demand);
public Card() {
}
public Card(String owner, int balance) {
this.owner = owner;
this.balance = balance;
}
public String getOwner() {
return owner;
}
public void setOwner(String owner) {
this.owner = owner;
}
public int getBalance() {
return balance;
}
public void setBalance(int balance) {
this.balance = balance;
}
}
package com.AnLi_gas_station;
public class customer_platinum extends Card{
@Override
public void pay(int prcie,int demand) {
double shoud_pay = prcie * 0.8 * demand;
System.out.println("今天的油价是:"+prcie+"/升,您是铂金会员折扣8折,需支付"+String.format("%.2f",shoud_pay)+"元");
}
}
package com.AnLi_gas_station;
public class customer_silver extends Card{
@Override
public void pay(int price,int demand) {
double shoud_pay = price * 0.85 * demand;
System.out.println("今天的油价是:"+price+"元/升,您是白银会员折扣8.5折,需支付"+String.format("%.2f",shoud_pay)+"元");
}
}
package com.AnLi_gas_station;
public class Main {
public static void main(String[] args) {
int price = 79;
int demand = 47;
customer_platinum platinum = new customer_platinum();
customer_silver silver = new customer_silver();
platinum.pay(price,demand);
silver.pay(price,demand);
}
}
运行结果:
今天的油价是:79/升,您是铂金会员折扣8折,需支付2970.40元
今天的油价是:79元/升,您是白银会员折扣8.5折,需支付3156.05元
抽象类的特征、注意事项(可面试)
在面试、笔试的时候也许会遇到这样的问题
特征和注意事项
- 普通类有的成员(成员变量、方法、构造器),抽象类也具备
- 抽象类中不一定有抽象方法,但有抽象方法的类一定是抽象类
- 一个类继承了抽象类必须重写完抽象类的全部抽象方法,否则这个类也必须定义成抽象类。
- 不能用abstract修饰变量、代码块、构造器。
- 被定义为抽象类的类虽然可以得到抽象方法,但是这个类不仅自身失去了创建自身对象的能力(有得有失),也不得被其他类创建为对象
final和abstract是什么关系(可面试)
- 互斥关系
- abstract定 义的抽象类必须作为模板让子类继承, final定 义的类则禁止被其他类继承。
- 抽象方法定义通用功能必须靠子类重写,final定义 的方法禁止子类进行重写。
抽象类的应用知识:模板方法模式
它是我们20多种设计模式当中的一种,请尽量了解掌握
什么时候使用模板方法模式
- 使用场景说明:当系统中出现同一个功能多处在开发,而该功能中大部分代码是一样的, 只有其中部分可能不同的时候。
模板方法模式实现步骤
- 把功能定义成一个所谓的模板方法,放在抽象类中,模板方法中只定义通用且能确定的代码。
- 模板方法中不能决定的功能定义成抽象方法让具体子类去实现。
理解模板方法:写作文案例
需求:
现在有两类学生, -类是中学生, -类是小学生,他们都要写《我的爸爸》这篇作文。
要求每种类型的学生,标题第一段和最后一段,内容必须一样。正文部分自己发挥。
请选择最优的面向对象方案进行设计。
分析:
模板注意事项
模板里面定义的方法我们是建议使用final修饰的,这样会更专业,那么为什么呢?
答:模板方法是给子类直接
使用的,而不是让子类去重写的,
一旦子类重写了模板方法,则模板方法就失效了,那我要这模板有何用,因此,加.上final后可以防止子类重写了模板方法,这样更安全、专业。
模板方法模式解决了什么问题?
提高了代码的复用性
模板方法已经定义了通用结构,模板方法不能确定的部分定义成抽象方法,交给子类实现,因此,使用者只需要关心自己需要实现的功能即可。