总是以提问的形式来开始我的总结 ,为什么会出现抽象类 ?有哪些应用 ?
上一次我们已经说过了 ,继承可以增加代码的复用性 ,子类可以把父类的方法拿过来直接用 ,也可以重写父类的方法 。那么好 ,假设有一个 Animal 父类中含有一个 “叫“ 方法 ,有 n 多个动物继承了 Animal ,结果由于动物的独特性每一个子类都需要重写父类的 “叫“ 方法 。那么问题来了 ,所有的子类都重写了父类的方法 ,我何必还要在父类中实现方法呢 ?
所以我们就可以把 “叫“ 这个方法给抽象化 ,这样就不用实现方法体了 ,岂不是美滋滋 。综上 ,我们可以把那些父类中没办法给出具体实现的方法给抽象化 。只需在方法的声明中添加 abstract 关键字即可 。但是此时编译会报错 ,因为含有抽象方法的类必须是抽象类 ,所以我们也要给类加上 abstract 。当然抽象类中可以包含非抽象的方法 。那为什么又说抽象类不能被实例化呢 。你想啊 ,我实例化一个对象 ,结果你给了我一个抽象的方法 ,我怎么去执行啊 ?很明显不行的嘛 。
如果你真的理解了抽象类的设计原理 ,那么理解模板设计模式应该不成问题 。顾名思义 ,模板设计模式就是指固定的套路 。假如你有如下需求 ,计算代码的运行时间 。套路就是记录开始时间 ,运行方法 ,记录结束时间 ,最后一减得出结果 。可以像这样实现 。
public abstract class SupClass { public abstract void run(); //这就是一个模板,限定为 final 防止子类重写该方法。 public final void calculateTime(){ long l1 = System.currentTimeMillis(); run(); long l2 = System.currentTimeMillis(); long time = l2 - l1; System.out.println("运行时间为 " + time + " 毫秒。"); } } public class Sub1Class extends SupClass{ @Override public void run() { System.out.println("在计算 Sub1Class 的 run 方法执行时间。。。"); long sum = 0; for (int i = 0; i < 1000000000; i++) { sum = sum + i; } } } public class Sub2Class extends SupClass{ @Override public void run() { System.out.println("在计算 Sub2Class 的 run 方法执行时间。。。"); long sum = 0; for (int i = 0; i < 10000000; i++) { sum = sum + i; } } } // 测试代码 public class TemplateTest { public static void main(String[] args) { SupClass class1 = new Sub1Class(); class1.calculateTime(); SupClass class2 = new Sub2Class(); class2.calculateTime(); } } 在计算 Sub1Class 的 run 方法执行时间。。。 运行时间为 350 毫秒。 在计算 Sub2Class 的 run 方法执行时间。。。 运行时间为 10 毫秒。