抽象类
1.1 概述
- Java中,abstract为抽象的意思,可以修饰类、成员方法
//格式
修饰符 abstract class类名{
修饰符 abstract 返回值类型 方法名(形参列表);
}
//例
public abstract Animal{
public abstract void run();
}
- 注意
- 抽象方法只能声明方法签名,不能声明方法体,即抽象方法没有{}
- 若类中定义了抽象方法,则此类必须声明为抽象类,否则报错
1.2 抽象类使用场景
-
抽象类可以理解为不完整的设计图,一般作为父类,让子类继承
-
当父类知道子类的某些行为时,但每个子类的行为具体实现都不相同时,父类可将此行为定义为抽象方法,交给子类去完成
- 即,子类有共同的行为,但具体的实现又各不相同, 此时可以将父类定义为抽象类,将行为定义为抽象方法,交给子类进行重写实现
-
也可理解为:制定规则;父类希望子类强行遵守这些规则,则可将方法定义为抽象方法,子类继承自父类后,必须重写抽象方法,否则无法运行
//案例:对于VIP卡客户,支付打8折,定义方法,输出支付信息
//Cards.java 定义父类,存储公共的信息
public abstract class Cards{
private String userName;
private double money;
public abstract void pay(double monry); //定义抽象方法
...;
}
//VipCards.java 定义子类
public class VipCards extends Cards{
@Override
public void pay(double money){ // 在子类中重写抽象方法
sout("当前消费:" + money);
sout("当前账户余额" + super.getMoney());
//计算实际消费
double cost = money * 0.8;
//更新账户
super.setMoney(super.getMoney - cost);
sout(super.getMoney);
}
}
//Test.java
public class Test{
public static void main(String[] args){
VipCards v = new VipCards(); //创建VipCards类对象
v.setName("张三");
v.setMoney(2000.0);
v.pay(200);
}
}
1.3 注意事项
- 一般类有的部分,抽象类都有(成员方法、成员变量、构造方法等)
- 抽象类中,不一定有抽象方法;有抽象方法的一定是抽象类
- 一个类继承了抽象类必须重写完成抽象类的全部抽象方法,否则这个类也不许定义为抽象类
- 原因:子类会继承父类的成员,所以也会将父类的抽象方法继承过去,若不进行重写,则子类中也有抽象方法,也需要将子类也定义为抽象类
- abstrac不能修饰变量、代码块、构造方法
- 最终要特征:抽象类得到了抽象方法,失去创建对象的能力(但依旧存在构造方法)
- 原因:
- 1.若允许创建对象,调用抽象方法时,抽象方法是没有方法体的,没有意义;
- 2.若抽象方法中,没有抽象方法,也是不允许创建对象的,就是为了防止后续加入了抽象方法、调用抽象方法的情况
- 3.依旧存在的原因:让子类访问其无参构造(子类构造方法都会默认访问父类的构造方法)
- final与abstrac为互斥关系
- final修饰类,类不能被继承;final修饰方法,方法不能被重写;
- abstract修饰类,是为了作为模板被子类继承;abstract修饰方法,是为了让子类重写;
1.4 模板方法模式
1.4.1 使用场景
- 当系统中出现同一个功能多处在开发,而该功能中大部分代码是一样的,只有部分可能不同
1.4.2 实现步骤
- 将功能定义为一个所谓的模板方法,放在抽象类中,模板方法中只定义通用且能确定的代码
- 模板中不能确定的功能,则定义成抽象方法,让具体的子类去实现
//Student.java
public abstract class Student{
public final void write(){ //final修饰模板方法,防止被重写而失去模板的作用,提高安全性
sout("开头");
writemid(); //调用抽象方法,会从调用者的类中调用此方法的具体实现
sout("结尾");
}
public abstract void writemid(); //定义抽象方法
}
//Child.java
public class Child extend Student{ //继承Student类
public void writemid(){ //重写抽象方法
sout("小学生写的");
}
}
//Test.java
public class Test{
public static void main(String[] args){
Child c = new Child();
c.write();
}
}