Java 深入接口和抽象类

作者: 还有236 | 来源:发表于2016-07-08 00:23 被阅读178次

    没能不能,只有肯不肯。


    一个软件的好坏,很大程度上取决于它的整体架构,整体架构其实可以看成对业务的一种架构框架的抽象,当代表逻辑设计的整体框架做好之后,底层的具体实现只需要考虑完成相应算法和一些基础的业务实现就可以了。当你需要开发另一个类似的项目时,以前的抽象框架层说不定可以再次使用。面向对象设计重要的是对抽象层的复用,而不是某一代码块的复用。

    在面向对象编程中,抽象是它的一大特征,有两种抽象类型来体现OOP的抽象:接口和抽象类。它们有太多相似的地方,导致有些人会认为接口和抽象类可以互换,但并不然,接口和抽象类的区别还是蛮大的。

    OOP面向对象的编程,如果要提高程序的复用率、可维护性和可扩展性,就要面向接口编程或 面向抽象类编程,把接口和抽象类作为程序抽象架构层中的顶端。

    接口

    接口在设计的初衷其实是对行为的抽象,在接口中可以定义变量以及方法,变量默认指定为              public static final ,方法为抽象方法,默认指定为 public abstract ,不可以有方法的实现,由实现该接口的类去实现该方法,并且接口中所有方法必须为抽象方法。从这里看出接口是一种极具抽象的类型,它比抽象类更“抽象”。

    抽象类

    顾名思义,包含抽象方法的类成为抽象类(但如果一个类中没有抽象方法,只用abstract修饰类,该类也为抽象类,也不能实例化),正因为抽象类中包含了没有具体实现的方法,所以抽象类不能实例化。如果一个类继承了抽象类,就要实现抽象类中所有的抽象方法。包含抽象方法的类成为抽象类,但并不是抽象类中全都是抽象方法,它也可以有成员变量和成员方法。

    抽象类和普通类的区别

    1、抽象类不能实例化,也就是不能用来创建对象。

    2、抽象类只能用 public 或 protected 来修饰,因为如果用 private,那抽象类就不能被继承,也就失去了意义,什么也做不了。

    3、抽象类被子类继承后,子类必须实现其所有的抽象方法,如果没有实现父类的抽象方法,则子类得定义为抽象类。

    语法上抽象类和接口的区别

    1、抽象类和接口之间最大的区别就是抽象类中可以有方法的实现,也可以有方法的定义,但接口中只能有方法的定义,不能有方法的具体实现。这是抽象类的优点,非常有用。(你给一个抽象类加一个具体实现的方法,那继承与这个抽象类的子类也就默认拥有了这个具体方法。如果是接口的话,就只能在接口中定义这个新方法,所有实现了这个接口的类就不能通过编译,只能将每个实现了这个接口的类来实现这个新方法才行,这显然是Java接口的缺点)在某些情况下抽象类更容易扩展。

    2、抽象类的实现只能由继承于它的子类来给出,所以这就要讲Java的单继承,一个类只能继承一个抽象类,作为一个抽象工具来说,效能会大打折扣。接口在这方面会比抽象类好很多,Java中一个类可以实现多个接口,从而这个类就具有了多种类型。可以看出接口是一个定义混合类型的理想工具,混合类型表示这个类不仅具有某个主类型的行为,还具有其他类型的行为。

    3、接口中不能出现静态方法和静态代码块,抽象类中可以出现静态方法和静态代码块(关于为什么学了以后在回答,知道的告知下)。

    通过以上几点,一个经典的设计模式就出来了:声明类型的工作仍然由接口来承担,这里我们给出一个抽象类,且实现了这个接口,而具体类可以选择实现接口,也可以选择继承抽象类,在层次结构中,接口是在最顶层,抽象类则在接口的下一层。这两个抽象类型的优点都能有所发挥,这就是  "缺省适配模式"。当你只想实现接口中一个或几个方法,而不想全都实现,这个设计模式能完美解决这个问题。

    接口和抽象类本身就是为了被具体类实现或者继承。如果在实际开发中,你准备使用具体类来继承具体类,那你的设计就有很大问题了。

    设计上接口与抽象类的区别

    抽象类是对事物本身的抽象,接口是对事物行为的抽象。什么意识呢?举个简单的例子:人和鱼,他们都会游泳,我们可以把人(People类)和鱼(Fish类)都单独设为一个类,但游泳是一种行为所以可以创建一个接口Swim,里头有个抽象方法 swim(),然后我们用People类和Fish类实现这个接口,至于程序员、架构师或者鲨鱼、鲸鱼这种不同身份的人和不同种类的鱼,只需要继承于People类或者Fish类就可以了,从这里我们可以看出,继承是"是不是"的关系(程序员是不是人),而接口是“有没有”的关系(人有没有游泳的行为)。如果一个类继承于抽象类,那这个类就是抽象类的种类,而实现接口是“有没有”的关系,例如:人是否会游泳?,会游泳就实现这个接口,否则就不实现。

    下面给一个网上流传广泛的例子:门和警报。门都有close()和open()两个行为,我们可以分别用抽象类和接口区定义它。

    如果这时需要在门上安装警报功能,我们提供两种方案:

    1、把三个功能都放进接口中,万一有个类只需要警报功能,不需要open()和close(),例如警报器,但实现了这个接口后,它三个功能都有了,这样的设计显然是不行的。

    2、把三个功能都放进抽象类中,那只要继承了抽象类的子类都具有了警报的功能,但有的门不具备警报功能,这样也显然不行。

    因为open()和close()是门的固有行为,警报是附加的行为。不如我们试试把open()和close()放在Door抽象类中,把警报功能单独放在Alarm接口中,然后设计一个警报门继承Door抽象类然后实现Alarm接口。

    本文主要参考于:http://www.cnblogs.com/dolphin0520/p/3811437.html

    http://blog.csdn.net/xw13106209/article/details/6923556

    相关文章

      网友评论

      • bbjoe: :clap: 抽象就是挖坑!

      本文标题:Java 深入接口和抽象类

      本文链接:https://www.haomeiwen.com/subject/ijxxjttx.html