问题描述:
星巴克咖啡冲泡法:
1.净水煮沸;
2.用沸水冲泡咖啡
3.将咖啡倒入杯子
4.加奶和糖
冲泡茶方法:
1.净水煮沸;
2.用沸水冲泡茶
3.将茶倒入杯中
4.加柠檬
问题思路:
仔细观察我们可以得知,虽为两种饮料但制作过程相似。**我们可以将其抽象出一个父类,相同的步骤可在父类中定义,不同的步骤可在父类中定义为抽象类,在子类中具体实现(方法覆写),**这样的好处是程序冗余度较低,易修改(即若要新加子类只需要子类继承父类,再具体实现抽象方法即可,删除即只删除子类即可)。
源代码如下:
abstract class Drink{//抽象父类
public void prepare(){
boilWater();
brew();
dropIntoCup();
add();
}
public void boilWater(){//净水煮沸与倒入杯中实则一样
System.out.println("1.煮沸水");
}
public void dropIntoCup(){
System.out.println("3.将饮料倒入杯中");
}
public abstract void brew();//抽象类
public abstract void add();
}
class Coffee extends Drink{
public void brew(){
System.out.println("2.泡咖啡");
}
public void add(){
System.out.println("4.加牛奶或糖");
}
}
class Tea extends Drink{
public void brew(){//父类中的抽象类在子类中具体实现
System.out.println("2.泡茶");
}
public void add(){
System.out.println("4.加柠檬");
}
}
public class Test{
public static void main(String[] args){
Drink drink1=new Coffee();//抽象类不可直接实例化对象,但可通过子类向上转型访问父类成员
drink1.prepare();//实例化对象调用prepare方法
Drink drink2=new Tea();
drink2.prepare();
}
}
源程序类图为:
程序运行结果:**
源程序演变过程:
//将Coffee类与Tea类独立开来
class Coffee{
public void prepare(){
boilWater();
brewCoffee();
dropCoffeeIntoCup();
addSugerAndMilk();
}
public void boilWater(){
System.out.println("1.用开水煮");
}
public void brewCoffee(){
System.out.println("2.泡咖啡");
}
public void dropCoffeeIntoCup(){
System.out.println("3.倒咖啡");
}
public void addSugerAndMilk(){
System.out.println("4.加牛奶或糖");
}
}
class Tea{
public void prepare(){
boilWater();
brewTea();
dropTeaIntoCup();
addLemon();
}
public void boilWater(){
System.out.println("1.开水煮");
}
public void brewTea(){
System.out.println("2.泡茶");
}
public void dropTeaIntoCup(){
System.out.println("3.将茶倒入杯中");
}
public void addLemon(){
System.out.println("4.加柠檬");
}
}
public class Test{
public static void main(String[] args){
Coffee coffee=new Coffee();
coffee.prepare();
Tea tea=new Tea();
tea.prepare();
}
}
此代码类图为:
此代码优点是通俗易懂,但代码冗余度高,不利于覆写。
//抽象出父类,将相同的操作放置与父类实现,子类继承即可
class Drink{
public void prepare(){
boilWater();
dropIntoCup();
}
public void boilWater(){
System.out.println("1.煮沸水");
}
public void dropIntoCup(){
System.out.println("3.将饮料倒入杯中");
}
}
class Coffee extends Drink{
public void prepare(){
boilWater();
brewCoffee();
dropIntoCup();
addSugerAndMilk();
}
public void brewCoffee(){
System.out.println("2.泡咖啡");
}
public void addSugerAndMilk(){
System.out.println("4.加牛奶或糖");
}
}
class Tea extends Drink{
public void prepare(){
boilWater();
brewTea();
dropIntoCup();
addLemon();
}
public void brewTea(){
System.out.println("2.泡茶");
}
public void addLemon(){
System.out.println("4.加柠檬");
}
}
public class Test{
public static void main(String[] args){
Coffee coffee=new Coffee();
coffee.prepare();
Tea tea=new Tea();
tea.prepare();
}
}
此程序类图为:
此程序相较于之前程序逻辑性加强,但任然冗余度高。于是利用抽象类与抽象方法书写时,就使得子类在不改变算法结构的情况下,重新定义算法中的某些步骤(子类具体实现抽象方法)。