目录
抽象类的定义与使用
定义
抽象类只是在普通类的基础上扩充了一些抽象方法而已。
抽象方法:指的是只声明而未实现的方法(没有方法体)。
所有抽象方法要求使用abstract来定义,并且抽象方法所在的类也一定要使用abstract来定义,表示抽象类。
抽象类的使用原则
1.所有的抽象类必须有子类。
2.抽象类的子类必须覆写抽象类的所有抽象方法(子类不是抽象类)。
3.抽象类想要实例化,必须通过子类向上转型为其实例化。
4.private与abstract不能同时使用。
举个栗子:
abstract class Person{
private String name; //属性
public String getName(){ //普通方法
return this.name;
}
public void setName(String name){
this.name = name;
}
//{}为方法体,抽象方法不包括方法体
public abstract void getPersonInfo(); //抽象方法
}
class Student extends Person{
public void getPersonInfo(){
System.out.println("I am a student");
}
}
public class Test{
public static void main(String[] args){
Person per = new Student();//通过向上转型实例化
per.getPersonInfo();//被子类覆写的方法
}
}
运行结果:
抽象类的相关规定
1.抽象类也允许提供构造方法,并且子类也照样遵循对象实例化流程,先调用父类构造方法而后调用子类构造方法。
2.抽象类中允许不定义任何抽象方法,但是此时抽象类依然无法直接创建实例化对象。
3.抽象类一定不能用final声明,因为用final声明的类不能被继承,但是抽象类必须有子类;抽象方法不能用private定义,因为抽象方法必须被覆写。
4.抽象类也分内部抽象类和外部抽象类。内部抽象类中可以使用static定义来描述外部抽象类。
抽象类的应用——模板设计模式
开闭原则(OCP):一个软件实体,如类、模块和函数应该对扩展开放,对修改关闭。
开闭原则是Java世界中最基础的设计原则。
在这里我们举个栗子:
我们平时准备柠檬茶的步骤:将水煮沸--->沸水浸泡茶叶--->把茶倒进杯子--->加柠檬
我们平时准备咖啡的步骤:将水煮沸--->沸水冲泡咖啡--->将咖啡倒进杯子--->加糖和牛奶
如果按照正常的思维,很多人会写两个类:茶和咖啡,分别实现它们不同的功能,但是很明显,冲泡咖啡和茶的步骤是很相似的,这时,我们就可以把一样的步骤写一个方法,用的时候直接调用,把相似的步骤写成抽象方法,要使用的时候自己实现。
我们先来看一下类图:
根据类图,写出如下代码:
/**
* 咖啡因饮料是一个抽象类
*/
abstract class CaffeineBeverage{
/**
* 现在用同一个prepareRecipe()方法处理茶和咖啡
* 用final声明是希望子类不要覆写这个方法
*/
final void prepareRecipe(){
boilWater();
brew();
pourInCup();
addCondiment();
}
/**
* 咖啡和茶处理这些方法不同,因此要定义为抽象类,留给子类实现
*/
abstract void brew();
abstract void addCondiment();
public void boilWater(){
System.out.println("将水煮沸");
}
public void pourInCup(){
System.out.println("倒入杯中");
}
}
class Tea extends CaffeineBeverage{
public void brew(){
System.out.println("沸水浸泡茶叶");
}
public void addCondiment(){
System.out.println("加柠檬");
}
}
class Coffee extends CaffeineBeverage{
public void brew(){
System.out.println("沸水浸泡咖啡");
}
public void addCondiment(){
System.out.println("加糖和牛奶");
}
}
public class Test{
public static void main(String[] args){
CaffeineBeverage tea = new Tea();
tea.prepareRecipe();
System.out.println("-------------------------------");
CaffeineBeverage coffee = new Coffee();
coffee.prepareRecipe();
}
}
运行结果:
我们刚刚实现的就是模板设计模式,它包含了实际的“模板算法”。
模板方法定义了一个算法的步骤,并允许子类为一个或多个步骤提供具体实现。