这不简单嘛,分别创建两个类:甲抄的试卷、乙抄的试卷
甲抄的试卷
/**
* @create on 2020/4/24 14:29
* @description 学生甲抄的试卷
* @author mrdonkey
*/
class TestPaperA {
/**
* 试题1
*/
fun testQuestion1() {
println("杨过得到,后来给了郭靖,练成倚天剑、屠龙刀的玄铁可能是[] a.球磨铸铁 b.马口铁 c.高速合金钢 d.碳素纤维")
println("答案:b")
}
/**
* 试题2
*/
fun testQuestion2() {
println("杨过、程英、陆无双铲除了情花,造成[] a.使这种植物不再害人 b.使一种珍稀物种灭绝 c.破坏了那个生物圈的生态平衡 d.造成该地区沙漠化")
println("答案:a")
}
/**
* 试题1
*/
fun testQuestion3() {
println("蓝凤凰致使华山师徒、桃谷六仙呕吐不止,如果你是大夫,会给他们开什么药?[] a.阿司匹林 b.牛黄解毒片 c.氟哌酸 d.让他们喝大量的生牛奶 e.以上全不对")
println("答案:c")
}
}
乙抄的试卷
/**
* @create on 2020/4/24 14:29
* @description 学生乙抄的试卷
* @author mrdonkey
*/
class TestPaperB {
/**
* 试题1
*/
fun testQuestion1() {
println("杨过得到,后来给了郭靖,练成倚天剑、屠龙刀的玄铁可能是[] a.球磨铸铁 b.马口铁 c.高速合金钢 d.碳素纤维")
println("答案:d")
}
/**
* 试题2
*/
fun testQuestion2() {
println("杨过、程英、陆无双铲除了情花,造成[] a.使这种植物不再害人 b.使一种珍稀物种灭绝 c.破坏了那个生物圈的生态平衡 d.造成该地区沙漠化")
println("答案:b")
}
/**
* 试题1
*/
fun testQuestion3() {
println("蓝凤凰致使华山师徒、桃谷六仙呕吐不止,如果你是大夫,会给他们开什么药?[] a.阿司匹林 b.牛黄解毒片 c.氟哌酸 d.让他们喝大量的生牛奶 e.以上全不对")
println("答案:a")
}
}
客户端类
/**
* @create on 2020/4/24 14:40
* @description 客户端测试
* @author mrdonkey
*/
class Client {
companion object {
@JvmStatic
fun main(vararg args: String) {
println("甲抄的试卷")
val paperA = TestPaperA()
paperA.testQuestion1()
paperA.testQuestion2()
paperA.testQuestion3()
println("乙抄的试卷")
val paperB = TestPaperB()
paperB.testQuestion1()
paperB.testQuestion2()
paperB.testQuestion3()
}
}
}
测试结果
甲抄的试卷
杨过得到,后来给了郭靖,练成倚天剑、屠龙刀的玄铁可能是[] a.球磨铸铁 b.马口铁 c.高速合金钢 d.碳素纤维
答案:b
杨过、程英、陆无双铲除了情花,造成[] a.使这种植物不再害人 b.使一种珍稀物种灭绝 c.破坏了那个生物圈的生态平衡 d.造成该地区沙漠化
答案:a
蓝凤凰致使华山师徒、桃谷六仙呕吐不止,如果你是大夫,会给他们开什么药?[] a.阿司匹林 b.牛黄解毒片 c.氟哌酸 d.让他们喝大量的生牛奶 e.以上全不对
答案:c
乙抄的试卷
杨过得到,后来给了郭靖,练成倚天剑、屠龙刀的玄铁可能是[] a.球磨铸铁 b.马口铁 c.高速合金钢 d.碳素纤维
答案:d
杨过、程英、陆无双铲除了情花,造成[] a.使这种植物不再害人 b.使一种珍稀物种灭绝 c.破坏了那个生物圈的生态平衡 d.造成该地区沙漠化
答案:b
蓝凤凰致使华山师徒、桃谷六仙呕吐不止,如果你是大夫,会给他们开什么药?[] a.阿司匹林 b.牛黄解毒片 c.氟哌酸 d.让他们喝大量的生牛奶 e.以上全不对
答案:a
以上的甲乙学生的代码存在非常多的相似逻辑,除了答案不同,没什么不一样,这样重复的代码维护两份之后改起来就很难改并且难以维护。例如,老师需要增加题目,那么甲乙两份都需要做修改,怎么解决呢?
老师出一份考卷,打印多分,让学生填答案即可。就是抽出一个公共的父类,将公共的逻辑都都上升到父类当中,而不是让每个子类去重复
提取的公共试卷类
/**
* @create on 2020/4/24 14:43
* @description 提取公共的模板类
* @author mrdonkey
*/
abstract class TestPaper {
/**
* 试题1
*/
fun testQuestion1() {
println("杨过得到,后来给了郭靖,练成倚天剑、屠龙刀的玄铁可能是[] a.球磨铸铁 b.马口铁 c.高速合金钢 d.碳素纤维")
println("答案:${answer1()}")
}
/**
* 试题2
*/
fun testQuestion2() {
println("杨过、程英、陆无双铲除了情花,造成[] a.使这种植物不再害人 b.使一种珍稀物种灭绝 c.破坏了那个生物圈的生态平衡 d.造成该地区沙漠化")
println("答案:${answer2()}")
}
/**
* 试题1
*/
fun testQuestion3() {
println("蓝凤凰致使华山师徒、桃谷六仙呕吐不止,如果你是大夫,会给他们开什么药?[] a.阿司匹林 b.牛黄解毒片 c.氟哌酸 d.让他们喝大量的生牛奶 e.以上全不对")
println("答案:${answer3()}")
}
protected abstract fun answer1(): String
protected abstract fun answer2(): String
protected abstract fun answer3(): String
}
学生甲的试卷只需填答案即可(具体的题目都复印出来了(在父类中写好了))
* @create on 2020/4/24 14:48
* @description 甲抄的试卷
* @author mrdonkey
*/
class TestPaperA : TestPaper() {
override fun answer1(): String {
return "b"
}
override fun answer2(): String {
return "c"
}
override fun answer3(): String {
return "a"
}
}
学生乙的考卷
/**
* @create on 2020/4/24 14:48
* @description 乙抄的试卷
* @author mrdonkey
*/
class TestPaperB : TestPaper() {
override fun answer1(): String {
return "c"
}
override fun answer2(): String {
return "a"
}
override fun answer3(): String {
return "a"
}
}
客户端测试
/**
* @create on 2020/4/24 14:54
* @description 客户端
* @author mrdonkey
*/
class Client {
companion object {
@JvmStatic
fun main(vararg args: String) {
println("甲抄的试卷")
val paperA: TestPaper = TestPaperA()
paperA.testQuestion1()
paperA.testQuestion2()
paperA.testQuestion3()
println("乙抄的试卷")
val paperB: TestPaper = TestPaperB()
paperB.testQuestion1()
paperB.testQuestion2()
paperB.testQuestion3()
}
}
}
测试结果同上。
当我们需要完成在某一细节层次的一个过程或一系列步骤,但其个别步骤在更详细的层次上的实现可能不同时,我们通常考虑用模板方法模式来处理。(如上的试卷题目相同,但是学生的答案可能不同)
模板方法模式 : 定义一个操作中的算法骨架,而将一系列步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
/**
* @create on 2020/4/24 14:59
* @description 抽象模板类
* @author mrdonkey
*/
abstract class AbstractClass {
/**
* 模板方法,给出了逻辑的骨架而逻辑的组成是一些相应的抽象类
* 他们都推迟到子类实现
*/
fun templateMethod() {
}
//原始操作1
abstract fun primitiveOperation1()
//原始操作2
abstract fun primitiveOperation2()
}
具体子类A
/**
* @create on 2020/4/24 15:04
* @description 具体的子类实现特定的逻辑操作
* @author mrdonkey
*/
class ConcreteClassA : AbstractClass() {
override fun primitiveOperation1() {
println("具体类A 方法1的实现")
}
override fun primitiveOperation2() {
println("具体类A 方法2的实现")
}
}
具体子类B
/**
* @create on 2020/4/24 15:04
* @description 具体的子类实现特定的逻辑操作
* @author mrdonkey
*/
class ConcreteClassB : AbstractClass() {
override fun primitiveOperation1() {
println("具体类B 方法1的实现")
}
override fun primitiveOperation2() {
println("具体类B 方法2的实现")
}
}
客户端测试
/**
* @create on 2020/4/24 15:09
* @description 客户端
* @author mrdonkey
*/
class Client {
companion object {
@JvmStatic
fun main(vararg args: String) {
val concreteA: AbstractClass = ConcreteClassA()
concreteA.primitiveOperation1()
concreteA.primitiveOperation2()
val concreteB: AbstractClass = ConcreteClassB()
concreteB.primitiveOperation1()
concreteB.primitiveOperation2()
}
}
}
测试结果:
具体类A 方法1的实现
具体类A 方法2的实现
具体类B 方法1的实现
具体类B 方法2的实现