场景:抄题目 给出答案
第一版程序:
学生A抄的试卷类:
package template1;
public class classpaperA {
public void TestQuestion1(){
System.out.println("题目1");
System.out.println("答案:a");
}
public void TestQuestion2(){
System.out.println("题目2");
System.out.println("答案:b");
}
public void TestQuestion3(){
System.out.println("题目3");
System.out.println("答案:c");
}
}
学生B抄的试卷类:
package template1;
public class classpaperB {
public void TestQuestion1(){
System.out.println("题目1");
System.out.println("答案:c");
}
public void TestQuestion2(){
System.out.println("题目2");
System.out.println("答案:a");
}
public void TestQuestion3(){
System.out.println("题目3");
System.out.println("答案:a");
}
}
客户端:
package template1;
public class maintest {
public static void main(String[] args) {
classpaperA a = new classpaperA();
a.TestQuestion1();
a.TestQuestion2();
a.TestQuestion3();
classpaperB b = new classpaperB();
b.TestQuestion1();
b.TestQuestion2();
b.TestQuestion3();
}
}
这样存在的问题是:两个学生抄试卷类非常相似,除了答案不同,没什么不一样,这样写还很容易出错,如果突然要改题目,两个人都需要改代码
可以抽象出一个父类,让两个子类去继承,公共的题目写到父类中
试卷父类:
package template2;
public class classpaper {
public void testQuestion1(){
System.out.println("题目1");
}
public void testQuestion2(){
System.out.println("题目2");
}
public void testQuestion3(){
System.out.println("题目3");
}
}
学生A子类:
package template2;
public class classpaperA extends classpaper{
@Override
public void testQuestion1() {
super.testQuestion1();
System.out.println("答案:a");
}
@Override
public void testQuestion2() {
super.testQuestion2();
System.out.println("答案:a");
}
@Override
public void testQuestion3() {
super.testQuestion3();
System.out.println("答案:c");
}
}
学生B子类:
package template2;
public class classPaperB extends classpaper {
@Override
public void testQuestion1() {
super.testQuestion1();
System.out.println("答案:a");
}
@Override
public void testQuestion2() {
super.testQuestion2();
System.out.println("答案:b");
}
@Override
public void testQuestion3() {
super.testQuestion3();
System.out.println("答案:c");
}
}
客户端同上
但还是由相同的代码,super.testQuestion(),System.out.println("答案:“); 除了选项abcd,其他都是重复的
所有重复的代码都应该上升到父类,而不是让每个子类都去重复。
添加一个虚方法answer():
package template3;
public class classpaperA {
public void testQuestion1(){
System.out.println("题目1");
System.out.println("答案"+answer1());
}
protected String answer1(){
return "";
}
public void testQuestion2(){
System.out.println("题目2");
System.out.println("答案"+answer2());
}
protected String answer2(){
return "";
}
public void testQuestion3(){
System.out.println("题目3");
System.out.println("答案"+answer3());
}
protected String answer3(){
return "";
}
}
学生A的试卷:
package template3;
public class test1 extends classpaperA {
@Override
protected String answer1() {
return "a";
}
@Override
protected String answer2() {
return "b";
}
@Override
protected String answer3() {
return "c";
}
}
学生B的试卷:
package template3;
public class test2 extends classpaperA {
@Override
protected String answer1() {
return "a";
}
@Override
protected String answer2() {
return "b";
}
@Override
protected String answer3() {
return "a";
}
}
package template3;
public class Main {
public static void main(String[] args) {
test1 A = new test1() ;
System.out.println("A的答案:");
A.testQuestion1();
A.testQuestion2();
A.testQuestion3();
test2 B = new test2();
System.out.println("B的答案:");
B.testQuestion1();
B.testQuestion2();
B.testQuestion3();
}
}
代码结构图:
如果有更多的学生,只需要在试卷的模板上填写答案
模板方法模式:定义一个操作中的算法的骨架,将一些步骤延迟到子类当中。模板方法使得子类可以不改变一个算法的结构即可重新定义该算法的默写特定步骤。
抽象类:
package template;
public abstract class AbstractClass {
public void templatemethod(){
operation1();
operation2();
}
public abstract void operation1();
public abstract void operation2();
}
具体实现类1:
package template;
public class classA extends AbstractClass {
@Override
public void operation1() {
System.out.println("具体类A的方法1实现");
}
@Override
public void operation2() {
System.out.println("具体类B的方法2实现");
}
}
具体实现类2:
package template;
public class classB extends AbstractClass {
@Override
public void operation1() {
System.out.println("具体类B的方法1实现");
}
@Override
public void operation2() {
System.out.println("具体类B的方法2实现");
}
}
客户端:
package template;
public class Main {
public static void main(String[] args) {
AbstractClass a;
a = new classA();
a.templatemethod();
a = new classB();
a.templatemethod();
}
}
模板方法模式通过把不变行为搬到超类,去除子类中的重复代码。