讲模板设计模式之前,我们用代码来实现咖啡和茶制作的类:
class Coffee {
/*
* 咖啡冲泡法(算法)
*/
void prepareRecipe() {
boilWater();
brewCoffeeGrings();
pourInCup();
addSugarAndMilk();
}
public void boilWater() {
System.out.println("将水煮沸");
}
public void brewCoffeeGrings() {
System.out.println("冲泡咖啡");
}
public void pourInCup() {
System.out.println("把咖啡倒进杯子中");
}
public void addSugarAndMilk() {
System.out.println("加糖和牛奶");
}
}
class Tea {
/*
* 冲泡茶法(算法)
*/
void prepareRecipe() {
boilWater();
steepTeaBag();
pourInCup();
addLemon();
}
public void boilWater() {
System.out.println("将水煮沸");
}
public void steepTeaBag() {
System.out.println("浸泡茶叶");
}
public void pourInCup() {
System.out.println("把茶倒进杯子中");
}
public void addLemon() {
System.out.println("加柠檬");
}
}
class Test {
public static void main(String[] agrs) {
Coffee coffee = new Coffee();
Tea tea = new Tea();
coffee.prepareRecipe();
tea.prepareRecipe();
}
}
实际上,浸泡(steep)和冲泡(brew)差异并不大。因此我们给它一个新的方法名称brew(),这样我们无论冲泡的是何种饮 料都可以使用这个方法。同样的,加糖、牛奶还是柠檬也很相似,都是在饮料中加入其它调料,因此我们也给它一 个通用名称addCondiments()。
/**
* 咖啡因饮料是一个抽象类
**/
abstract class CaffeineBeverage {
/**
* 现在用同一个prepareRecipe()方法处理茶和咖啡。
* 声明为final的原因是我们不希望子类覆盖这个方法!
**/
final void prepareRecipe() {
boilWater();
brew();
pourInCup();
addCondiments();
}
/**
* 咖啡和茶处理这些方法不同,因此这两个方法必须被声明为抽象,留给子类实现
**/
abstract void brew();
abstract void addCondiments();
void boilWater() {
System.out.println("将水煮沸");
}
void pourInCup() {
System.out.println("把饮料倒进杯子中");
}
}
class Coffee extends CaffeineBeverage {
public void brew() {
System.out.println("冲泡咖啡");
}
public void addCondiments() {
System.out.println("加糖和牛奶");
}
}
class Tea extends CaffeineBeverage {
public void brew() {
System.out.println("浸泡茶叶");
}
public void addCondiments() {
System.out.println("加柠檬");
}
}
class Test {
public static void main(String[] agrs) {
CaffeineBeverage coffee = new Coffee();
CaffeineBeverage tea = new Tea();
coffee.prepareRecipe();
tea.prepareRecipe();
}
}
钩子方法是一类"默认不做事的方法" ,子类可以视情况决定要不要覆盖它们。
比如说,顾客点杯咖啡时,可以选择加不加牛奶或者糖!!!
import java.util.Scanner;
/**
-
咖啡因饮料是一个抽象类
/
abstract class CaffeineBeverage {
/
- 现在用同一个prepareRecipe()方法处理茶和咖啡。
- 声明为final的原因是我们不希望子类覆盖这个方法!
/
final void prepareRecipe() {
boilWater();
brew();
pourInCup();
if(customerWantsCondiments())
addCondiments();
}
/
- 咖啡和茶处理这些方法不同,因此这两个方法必须被声明为抽象,留给子类实现
**/
abstract void brew();
abstract void addCondiments();
void boilWater() {
System.out.println("将水煮沸");
}
void pourInCup() {
System.out.println("把饮料倒进杯子中");
}
boolean customerWantsCondiments() {
return true;
}
}
class Coffee extends CaffeineBeverage {
public void brew() {
System.out.println("冲泡咖啡");
}
public void addCondiments() {
System.out.println("加糖和牛奶");
}
/**
* 子类覆写了钩子函数,实现自定义功能
**/
boolean customerWantsCondiments() {
String result = getUserInput();
if(result.equals("y"))
return true;
else
return false;
}
private String getUserInput() {
System.out.println("您想要在咖啡中加入牛奶或糖吗(y/n)?");
Scanner scanner = new Scanner(System.in);
String str = scanner.nextLine();
return str;
}
}
class Tea extends CaffeineBeverage {
public void brew() {
System.out.println("浸泡茶叶");
}
public void addCondiments() {
System.out.println("加柠檬");
}
}
class Test {
public static void main(String[] agrs) {
CaffeineBeverage coffee = new Coffee();
CaffeineBeverage tea = new Tea();
coffee.prepareRecipe();
tea.prepareRecipe();
}
}
转载:https://blog.csdn.net/sifanchao/article/details/83418339
原文:https://www.cnblogs.com/blogcpp/p/13382060.html