zoukankan      html  css  js  c++  java
  • 【java基础 16】抽象类和接口的区别

    导读:前两天闲着没事儿,看了本书,然后写了点代码,在接口里面写了默认方法实现,因为书上说这个特性是从java8开始的,我还特地给测了一下java7. 没过几天,就有一个技术分享会,刚好也是讲java8特性,然后,顿时就觉得世界观被毁了!怎么回事呢,看下文吧:


    还记得,当年我刚面试的时候,面试官问我接口和抽象类什么区别,我张口就来了传说中的标准答案,那时候是解释不清楚接口和抽象类各自的用途的和来源的,就记得我说了很重要的一条就是:抽象类里面可以有方法实现,而接口是不可以的。哈哈哈哈,java8出来之后,我竟无言以对!

    一、基本概念

    1.1,抽象类

    从语义的角度来看,抽象类是从多个具体类中抽象出来的父类,它具有更高层次的抽象,体现了is-a的逻辑。从多个具有相同特征的类中抽象出一个抽象类,以这个抽象类作为其子类的模板,从而避免了子类设计的随意性。

    从根本上来说,抽象类体现的是一种模板模式的设计,它作为子类的通用模板,允许其子类在它的基础上扩展、改造,但是,子类总体上会大致保留抽象类的行为方式!(就跟个如来佛似的,孙悟空那么厉害,我允许你蹦跶蹦跶蹦,但你这猴子,还得听我的是不)

    1.2,接口

    抽象类是从多个类中抽象出来的模板,将抽象更进一步,就可以折腾出一个更高逼格的别样“抽象类”——接口!体现了has-a的逻辑。

    接口定义了某一批类所需要遵守的规范,它并不关心这些类的内部状态数据,也不关心这些类里方法的实现细节,它只规定这批类里必须提供某些方法,满足实际需要。它体现的是一种规范和实现向分离的设计哲学。


    八卦模式:接口让我想起了邓爷爷的一句话:管他黑猫白猫,抓到耗子就是好猫!接口就是这样子的一个体现:管你动物类植物类,接口实现了就是好的! 要是当年如来佛公布一个去西天的接口,然后定义了一个取经的方法,会发生什么?  (群魔乱舞,各显神通,但是这妖魔神仙多了,嘿嘿。。。。) 拿要是他老人家公布的是一个去西天的抽象类,然后定义了一个取经的方法,又会发生什么?


    二、思考过程

    2.1,体现在内存分配

    因为接口里面只能是类成员变量、类方法或默认方法、内部类等,而抽象类里面的变量和方法可以是实例成员变量或方法。我就在想,如果使用接口的话,那么方法和变量势必会在JVM启动时,就会被加载分配到内存,从而增加程序启动的开销,反之抽象类就不一样了。   不过,我这个想法被否了,说是现在的虚拟机经过一带一带的改进,从这个角度上来说,使用接口和抽象类的内存影响差不多!除非我刻意写了坏味道的代码。。。本宝宝表示不懂啊

    2.2,体现在多继承

    因为一个类可以同时实现很多个接口,而一个类不可以同时继承多个类

    2.3,体现在访问控制层面

    又回到了接口可用的访问控制,方法只能是静态或默认,变量只能是静态 final等,而接口默认的访问控制是public。反之抽象类,可以是public、private、protected等!


    知道我为什么这么纠结这个抽象类和接口的区别吗?因为从java8出来之后,有人问你觉得抽象类还有存在的必要吗,抽象类可以实现的,接口都可以做到!然后,那时我还是个宝宝,但后来越想越不对,所谓存在即合理对吧!


    三、主要异同点

    3.1,相同点

    1,都不能被实例化,位于继承树的顶端,用于被其他类实现和继承

    2,都可以包含抽象方法,实现接口或继承抽象类的普通子类都必须实现这些抽象方法


    3.2,不同点

    1,目的和作用不同

    接口是系统与外界交互的窗口(模块或系统之间提供服务窗口,有听说是调用抽象类的不?)它体现的是一种规范。对于接口的实现者,它规定了实现者必须提供的服务;对于接口的调用者,它则规定了调用者可以调用的服务,以及如何调用这些服务。当在一个程序中使用接口时,接口时多个模块间的耦合标准;当在多个程序中时,它就是多个程序之间的通信标准。

    抽象类是系统中多个子类的共同父类,它可以被当成系统实现过程中的中间产品,这个产品已经实现了系统的部分功能,但它并不是一个成熟的产品,必须由其子类去进一步完善!

    PS:有没有感觉接口的设计层面和抽象类不一样?想一想机房收费系统,接口可以作为独立的一层去设计,而没有抽象类层!

    2,在用法上不同

    抽象类可以包含普通方法;接口不能定义静态方法(注意区别java8接口可以有静态和默认方法实现);抽象类可以定义普通成员变量;抽象类可以拥有构造器,让其子类利用它完成抽象类的初始化操作;接口无法拥有初始化块;接口可以弥补java单继承的不足。


    四、总结

    我总觉得抽象类和接口比起来,接口更好用,先不说抽象类继承破坏了父类的封装性(用组合模式解决)再着就是目前的使用过程中得到的体会,比如说Animal A=new Dog();这个向上转型,还有就是如果程序真的出了点问题需要改的话,那么势必也会改到这一行代码,现在Spring容器通过IOC创建对象,这个可能就不算事儿了!

  • 相关阅读:
    Codeforces 877 C. Slava and tanks
    Codeforces 877 D. Olya and Energy Drinks
    2017 10.25 NOIP模拟赛
    2017 国庆湖南 Day1
    UVA 12113 Overlapping Squares
    学大伟业 国庆Day2
    51nod 1629 B君的圆锥
    51nod 1381 硬币游戏
    [JSOI2010]满汉全席
    学大伟业 2017 国庆 Day1
  • 原文地址:https://www.cnblogs.com/hhx626/p/7534608.html
Copyright © 2011-2022 走看看