抽象类(以及模板方法设计模式)

总结理解的模板方法设计模式及抽象类

(菜鸟一只,若有什么侵权或者不足之处,请指出,谢谢)

 

模板方法设计模式:

         在父类中定义一个总体的算法骨架,而将一些具体的实现步骤放在到子类中,因为不同的子类实现细节不同
         模板方法使得子类可以在不改变算法框架的情况下,只需要重新定义算法的某些实现步骤(借助于抽象类实现

 

模板方法:一种统一的处理方式,即模板(比如课设报告,大家都按照规定同一种的格式去写,这就是模板,但是课设的题目不同,其具体内容是不同的)

 

该模式主要优点如下:
        (1)封装了不变部分,扩展可变部分。它把认为是不变部分的算法封装到父类中实现,而把可变部分算法由子类继承实现,便于子类继续扩展。
        (2)在父类中提取了公共的部分代码,便于代码复用。
        (3)部分方法是由子类实现的,因此子类可以通过扩展方式增加相应的功能,符合开闭原则。


该模式主要缺点如下:
        (1)对每个不同的实现都需要定义一个子类,这会导致类的个数增加,系统更加庞大,设计也更加抽象。
        (2)父类中的抽象方法由子类实现,子类执行的结果会影响父类的结果,这导致一种反向的控制结构,它提高了代码阅读的难度
 

注意:
         抽象父类提供的模板方法只是定义了一个通用的算法,其实现必须通过子类的辅助
         模板方法作为模板样式不允许被子类覆盖

例如:

class StringOperate{
    
    //需求:求String的连续1000次拼接的时间
    public static long stringAppend() {
        long startTime = System.currentTimeMillis();//开始时间
        String str = "";
        for(int i = 0 ; i < 1000 ; i++) {
            str += 1;
        }
        
        long endTime = System.currentTimeMillis();//结束时间
        
        long time = endTime - startTime;//时间差
        return time;
    }
}
class IntOperate{

    //需求:int类型的连续100000次加1的时间
    public static long intAppend() {
        long startTime = System.currentTimeMillis();//开始时间
        int num = 0;
        for(int i = 0 ; i < 100000 ; i++) {
            num += 1;
        }
        
        long endTime = System.currentTimeMillis();//结束时间
        
        long time = endTime - startTime;//时间差
        return time;
    }
}    

 

倘若有很多如上面类似的行为,则代码存在大量重复现象

可修改为:

abstract class AbstractOperateTimeLate{
//模板方法
public long getTotalTime() { long startTime = System.currentTimeMillis();//开始时间模板方法 //具体操作(留给子类完成) operateTime(); long endTime = System.currentTimeMillis();//结束时间 long time = endTime - startTime;//操作 计算时间差 return time; } //抽象方法 具体实现在子类重覆盖本抽象方法里面 protected abstract void operateTime(); } class StringOperate extends AbstractOperateTimeLate{ //计算String拼接1000次的时间 (在其他子类中也可以通过覆盖抽象类中的抽象方法来实现其他操作的时间差)抽象类的具体实现 @Override protected void operateTime() { String str = ""; for(int i = 0 ; i < 1000 ; i++) { str += 1; } } } public class TestDemo01 { public static void main(String[] args) { long time = new StringOperate().getTotalTime();//调用父类中的模板方法 System.out.println(time); } }

 

抽象类的概念

   在继承的层次结构中,每个子类的行为(功能实现)会越来明确,如果追溯到父类,类会变得更通用,更加不明确。类的设计应该确保父类包含它的子类的共同特性。有时候,一个父类设计的非常抽象,以至于没有任何具体的实例,这样的类称为抽象类

  Java中允许在类中只声明方法而不提供方法的实现。这种只有声明而没有方法体的方法成为抽象方法,而包含一个或者多个抽象方法的类称为抽象类。
抽象方法是通过指定abstract关键字来创建。抽象方法没有内容,因此不需要被父类执行。

  抽象类是为了把子类中具有共同特性但是实现细节不同的东西提取出来,达到代码复用的目的。抽象方法的具体实现在子类中(注意:如果定义了一个抽象类,当子类继承一个抽象类时,子类要重写父类中的所有抽象方法,否则需要将子类也声明为abstract抽象类

 

 

抽象类需要注意几点:

(1)一个抽象类只关心是否具有某种功能,而不关心功能的具体实现,功能的具体行为和属性由子类负责实现,所以抽象类不能被实例化。因为抽象类中方法未具体化,这是一种”不完整”的类,直接实例化也就没有意义。

(2)抽象类中不一定要包含抽象(abstract)方法。抽象类中可以没有抽象方法。但是一旦类中包含了抽象方法,那类该类必须声明为抽象类。

(3)抽象类中不一定只有抽象方法,可以有普通方法。抽象类通过子类来调用和实现抽象方法和普通方法。

 

 

参考:梁勇.Java语言程序设计.机械工业出版社

   本文中模板设计模式有部分内容借鉴于:http://c.biancheng.net/view/1378.html

 

点赞