-
抽象体现的就是一种模板模式的设计,抽象类作为多个子类的通用模板,子类在抽象类的基础上进行扩展,改造,但子类总体上会保留抽象类的行为方式
-
**
解决的问题: 当功能内部一部分实现是确定的,一部分实现是不确定的。这时可以把不确定的部分暴露出去,让子类去实现。 换句话说,在软件开发中实现一个算法时,整体步骤很固定,通用,这些步骤已经在父类中写好了。但某些部分易变,易变部分可以用抽象出来,供不同的子类实现,这就是一种模板模式
**
代码实现
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)存在一种反向的控制结构,通过一个父类调用其子类的操作,通过子类对父类进行扩展增加新的行为,符合“开闭原则”。