抽象体现的就是一种模板模式的设计,抽象类作为多个子类的通用模板,子类在抽象类的基础上进行扩展,改造,但子类总体上会保留抽象类的行为方式
**
解决的问题: 当功能内部一部分实现是确定的,一部分实现是不确定的。这时可以把不确定的部分暴露出去,让子类去实现。 换句话说,在软件开发中实现一个算法时,整体步骤很固定,通用,这些步骤已经在父类中写好了。但某些部分易变,易变部分可以用抽象出来,供不同的子类实现,这就是一种模板模式
** 代码实现
package TemplateMethod; /* * 抽象类的应用: * 模板设计模式: * 银行业务 */ public class BankQueuing { public static void main(String[] args) { fun(new Customer()); fun(new Customer() { @Override public void business() { System.out.println("存钱"); } }); } public static void fun(TemplateBank Test) { Test.implementation(); } } abstract class TemplateBank{ public TemplateBank() { } public void Take() { System.out.println("取号......"); } public void YourTurn() { System.out.println("叫号......"); } //业务 //不确定项 public abstract void business(); public final void implementation() { Take(); YourTurn(); business(); System.out.println("-----------------"); } } class Customer extends TemplateBank{ public Customer() { } @Override public void business() { System.out.println("取钱"); } }运行图
模板模式实现代码的运行时间:
package TemplateMethod; /* * 抽象类的应用: * 模板设计模式 */ public class TemplateTest { public static void main(String[] args) { //求质数 Template Test = new SubTemplate(); Test.spendTime(); //快排 int arr[][] = new int[10][20]; Template Test1 = new QuickArray(arr); Test1.spendTime(); } } abstract class Template{ //计算代码花费的时间 public void spendTime() { long start = System.currentTimeMillis(); //调用子类重写方法 code(); long end = System.currentTimeMillis(); System.out.println("程序花费的时间为:"+(end-start)+"毫秒"); } //未知程序 public abstract void code(); } class SubTemplate extends Template{ public SubTemplate() { } //测试1000以内的质数 @Override public void code() { boolean falg = false; for (int i = 2 ; i <= 1000; i++) { falg = false; for (int j = 2; j <= Math.sqrt(i); j++) { if(i % j == 0) { falg = true; break; } } if(!falg) { System.out.println(i); } } } } class QuickArray extends Template{ int arr[][]; public QuickArray(int arr[][]) { this.arr = arr; } @Override public void code() { for (int i = 0; i < arr.length; i++) { for (int j = 0; j < arr[0].length; j++) { arr[i][j] = (int)(Math.random()*100+1); } } for (int i = 0; i < arr.length; i++) { quickArray(arr, 0, arr[0].length-1,i); } for (int i = 0; i < arr.length; i++) { for (int j = 0; j < arr[0].length; j++) { System.out.printf("%d ",arr[i][j]); } System.out.println(); } } public void quickArray(int arr[][],int left,int right,int line) { if(left > right) return; int temp = arr[line][left]; int i = left; int j = right; while(i != j) { while(arr[line][j] >= temp && i < j) { j--; } while(arr[line][i] <= temp && i < j) { i++; } int num = arr[line][j]; arr[line][j] = arr[line][i]; arr[line][i] = num; } arr[line][left] = arr[line][j]; arr[line][j] = temp; quickArray(arr, left,i-1, line); quickArray(arr, i+1,right, line); } }运行图
总结:
(1)具体细节步骤实现定义在子类中,子类定义详细处理算法是不会改变算法 整体结构。 (2)代码复用的基本技术,在数据库设计中尤为重要。 (3)存在一种反向的控制结构,通过一个父类调用其子类的操作,通过子类对父类进行扩展增加新的行为,符合“开闭原则”。