抽象类?这个东西我感受没什么卵用啊,又不能拿来new对象,没有具体的对象的抽象类,有什么实际的意义呢?这是不少刚刚接触java抽象类语法时的第一反应(固然,包括我)。确实,不少刚刚接触抽象类这个概念的程序员都没法真正理解抽象类存在的意义,感受java中的这个专门只能拿来继承并实现了对应抽象方法才能真正有那么一点用处的父类确实有点多余。java
确实,若是你只是一个应用开发者(固然,是指简单地实现业务功能),或许你永远也不用抽象类,由于,它原本就不是拿来当具体的应用功能开发用的类,它是用来实现传说中的架构建模用的,没错,就是这个简答的抽象类,是架构师构建大型架构必不可少的工具,废话很少说,下面咱们一块儿感觉抽象类在架构设计中的威力(固然,真正的 威力确定比我描述的强大得多,毕竟,目前我对抽象类的架构建模思想也是懂点皮毛,或许皮毛都不算)程序员
1、具体类实现功能web
在讨论抽象类前,咱们先简单地讨论具体类的一些例子,以便和抽象类进行对比,好了,首先看一个很稀松例子:编程
//一个简单的汽车类 class Car{ //该类有如下方法 //点火方法 public void fire(){ System.out.println("我是汽车,给我点火,个人发动机会开始转动"); } //驾驶方法 public void run(){ System.out.println("我是车,我如今在驾驶,注意,我和倒车不一样,我是向前走"); } //倒车方法 public void backCar(){ System.out.println("我是车,我如今在倒车,注意,我和驾驶不一样,我是向后走"); } //如今有一个动做:放置好车辆(好吧,这个说法有点牵强,只是为了说明例子,别太在乎) public void setCar(){ //首先,你要对车点火才能驱动车行驶,才能将车放到车库(原谅我这里的不面向对象,一切只为说明问题实质) fire(); //恩,向前走,去到车库 run(); //ok,我要倒车入库了 backCar(); //...固然,后续其余操做:熄火啊什么的 } }
好吧,代码有点长,可能你如今一脸懵逼不知道我为毛举一个这么脑残的例子(稍后估计你就明白了),这里的代码就是咱们平时不少时候编程的大概思惟方式:类方法内部调用其余方法,并且这个类是具体的,方法也是具体的,咱们当时想的只是:我要事先车这个功能,例如说,我只是要倒车入库,我如今实现了,那就行啦,这样代码运行的不错,恩,咱们开始沾沾自喜,感受本身干了件大事,以为java程序设计不过如此,简单啦。设计模式
确实,上面这个例子,在现阶段,很好地实现了咱们须要的功能,然而,然而,估计你是个程序员,你就会知道,需求,一直在变,程序也要一直变,正如个人上一篇讨论设计模式的博客说到:咱们要保证咱们的设计具备可扩展性。架构
因此,看看咱们上面这个例子的可扩展性如何:加入,个人车不是普通的车,个人车是宝马,宝马啊,他妈的怎么能和普通车同样?个人run方法但是时速超过200km的,你怎么能只是简单地说我只是在往前走地描述个人驾驶状态?因此,这是候,上面的代码没辙了,只能新建一个BMW类,而后乖乖地继承car类,而后乖乖地重写全部方法,而后,你会发觉:这个更高级别的car存在的意义彷佛并不大?下面是继承后的BMW类的代码:框架
class Bmw extends Car{ //我是宝马,个人点火方法不同凡响 public void fire(){ System.out.println("我是宝马,给我点火,个人发动机会开始转动,而且哥点火时的气势可不是那些普通车可比的"); } //宝马驾驶方法 public void run(){ System.out.println("我是宝马,我如今在驾驶,注意,我是在飞奔驾驶,别将我和那些垃圾普通奇瑞qq类比"); } //宝马倒车方法 public void backCar(){ System.out.println("我是车,我如今在倒车,由于我是宝马,倒车姿式确定也不是通常酷"); } //如今要放好个人宝马车了 public void setCar(){ //首先,轰轰,点火 fire(); //恩,向前飞奔,注意,是飞奔 run(); //ok,我要倒车入库了 backCar(); //...固然,后续其余操做:熄火啊什么的 } }
因此,做为程序员的你开始抱怨:为毛感受父类在这里没什么做用了?它做用表如今哪?我还不是要从新所有方法覆盖一遍!因此,这时候,抽象类的威力就出来,下面看用抽象类改造后的例子;工具
2、抽象类进行更高层次的建模post
先看利用抽象类进行更高层次的建模吧,估计看完代码你就大概能领悟抽象类再架构设计中是大概如何发挥做用的了:spa
//我是一个抽象的汽车类,注意,是抽象的 abstract class car{ //和上面例子同样,我有下面这些方法,只不过,部分方法抽象化了 public abstract void fire(); public abstract void run(); public abstract void backCar(); //而后,下面这个方法不是抽象的(是的,java抽象类容许非抽象方法存在),由于,它对应全部的car都适用(也是高层次进行动做抽象的表现) public void setCar(){ //我调用抽象方法,不用担忧,这些抽象方法会在子类中实现! fire(); run(); backCar(); } }
好了,有没有领会到我大概要表达的意思和传递的思想了呢:在上面中,我就是利用car的抽象类,定义了setCar的具体方法,这是由于对应全部车来讲setCar都是这几个动做(fire,run,backCar),因此,这是肯定的——setCar必须确定是调用这几个方法的,因此具体化;而fire,run,backCar针对不一样的车有不一样的方式,因此要抽象化,而后,子类只须要实现抽象类具体方法就好了,而后,对于全部的car来讲,咱们能够复用父类的setCar代码(毕竟全部车的setCar动做同样),而,这,不就是基础的好处了吗?好了,看下面的BMW家伙在利用抽象类进行建模后的改进写法:
class Bmw extends car{ public void fire() { System.out.println("我是宝马,给我点火,个人发动机会开始转动,而且哥点火时的气势可不是那些普通车可比的"); } public void run() { System.out.println("我是宝马,我如今在驾驶,注意,我是在飞奔驾驶,别将我和那些垃圾普通奇瑞qq类比"); } public void backCar() { System.out.println("我是车,我如今在倒车,由于我是宝马,倒车姿式确定也不是通常酷"); } //而后,咱们就能够直接复用car父类中的setCar方法啦!直接调用便可,达到了复用代码的目的! }
这时,估计你应该能体会到抽象类的一些威力了吧?它在更高的层次进行一个类组织的规范,这个抽象类知道大致上这个类该如何组织,如何运行,可是运行细节其实子类来决定的(子类实现对应抽象方法),这些,不正是不少web框架设计的经常使用手段吗!
因此,架构就这样来了,架构师在更高层次抽象系统的类之间、类内部的调度关系,而实现开发人员只须要实行具体的方法就能够了,毕竟,类之间的关系,架构师已经规划好了。
另外,这样还有另外的好处就是:扩展性。我想新增一种车,只须要基础抽象类Car便可,setCar操做会根据我新的类型的car的方法进行不一样的内部动做,而我原来的代码并不须要一点点的改变!这样,符合扩展的不修改源代码而利用新增代码达到扩展的原则。
So,抽象类,的确,很不错是吧,毕竟,虽然它不是具体的执行者(不能new),可是,它充当的确实帝王角色,专门负责指挥具体的方法去作事,因此我认为:抽象类的设计,就是一套系统的架构规范的设计!