模板方法的概念
1、规定一个执行流程,所有对象的执行过程都依据这个流程
2、把所有对象中相同操作的步骤直接实现,封装在这个框架中
3、把因对象而异的操作交由具体的对象子类实现
模板方法举例
这里用学生体测举一个例子:
体测有多个不同项目,其中包括全部人都要测试的项目,也包括因人而异的项目,比如男生要测引体向上,而女生要测仰卧起坐。
在模板方法中,我们规定一个体测的具体流程,如先测身高体重(First),再测试跑步(Second),最合测试引体向上/仰卧起坐(Third)。
其中,测身高体重是男女都必需的测试,跑步和力量测试则是因性别而异的测试
综上所述,我们需要在模板方法中声明三个测试方法以及一个开始体测的方法,并在开始体测的方法中有序调用三个体测
代码示例
//模板方法基类
class abstract Test
{
//开始体测的方法,使用final修饰,让子类不可更改,以确保子类遵守这个流程
public final void startTest(){
FirstTest();
SecondTest();
ThirdTest();
}
//测身高体重,所有学生相同的操作,直接实现
private void FirstTest(){
system.out.println("测试身高体重");
}
//测试跑步,因性别而异,让子类实现
protected abstract void SecondTest();
//测试力量,因性别而异,让子类实现
protected abstract void ThirdTest();
}
//男学生测试类
class MaleTest extends Test
{
@Override
protected void SecondTest(){
system.out.println("测试跑步1000米");
}
@Override
protected void ThirdTest(){
system.out.println("测试引体向上");
}
}
//女学生测试类
class FemaleTest extends Test
{
@Override
protected void SecondTest(){
system.out.println("测试跑步800米");
}
@Override
protected void ThirdTest(){
system.out.println("测试仰卧起坐");
}
}
//示例
class TestDemo
{
public static void main(String[] args)
{
Test student1 = new MaleTest();
student1.startTest();
Test student2 = new FemaleTest();
student2.startTest();
}
}
扩展
上述过程大致上完成了正常的男女学生的体测流程,然而,在实际的体测中,并不是所有的学生都需要参加测试的,有部分学生可能由于身体条件或疾病的原因,是可以不参加测试的,那么这些学生按照上面的流程就走不通了,因此,我们需要对这个模板方法的体测流程进行改造
//模板方法基类
class abstract Test
{
//开始体测的方法,使用final修饰,让子类不可更改,以确保子类遵守这个流程
public final void startTest(){
FirstTest();
if (isNeedTest())
{
SecondTest();
ThirdTest();
}
}
//测身高体重,所有学生相同的操作,直接实现
private void FirstTest(){
system.out.println("测试身高体重");
}
//测试跑步,因性别而异,让子类实现
protected abstract void SecondTest();
//测试力量,因性别而异,让子类实现
protected abstract void ThirdTest();
//是否需要测试Second和Third
protected boolean isNeedTest(){
return true;
}
}
如代码所示,我们增加了一个判断方法,用来判断学生是否需要参加跑步和力量测试,默认返回为true,如果返回false,则不走Second和Third的流程
新建一个特殊情况的测试对象类,重写isNeedTest方法,返回false
class SpecialTest extends Test
{
@Override
protected void SecondTest(){
//不需要测试
system.out.println("此处不打印");
}
@Override
protected void ThirdTest(){
//不需要测试
system.out.println("此处不打印");
}
@Override
protected boolean isNeedTest(){
return false;
}
}
class TestDemo
{
public static void main(String[] args)
{
//男学生体测
Test student1 = new MaleTest();
student1.startTest();
//女学生体测
Test student2 = new FemaleTest();
student2.startTest();
//特殊情况,只测试身高体重
Test student3 = new SpecialTest();
student3.startTest();
}
}
当student3执行开始体测时,只会打印身高体重的测试,而不用再进行跑步和力量测试了