• 抽象类和接口的对比


    抽象类 —— 一种模板式设计

    1 abstract void fun();
    2 [public] abstract class ClassName {
    3     abstract void fun();
    4 }
    • 抽象类就是为了继承而存在
    1. 抽象类不能被实例化,实例化 交由它的子类完成,它只需要有一个引用即可。
    2. 抽象方法必须由子类来进行重写。必须为public或者protected,缺省情况下默认为public
    3. 只要包含一个抽象方法的抽象类,该方法必须要定义成抽象类,不管是否还包含有其他方法。
    4. 抽象类中可以包含具体的方法,当然也可以不包含抽象方法。
    5. abstract不能与final并列修饰同一个类。
    6. abstract 不能与privatestaticfinalnative并列修饰同一个方法。
    • 抽象类的意义在于:
    1. 为其子类提供一个公共的父类型,避免该类被实例化;
    2. 封装子类中的重复内容(成员变量和方法);
    3. 定义公共抽象方法,由子类提供不同的实现。

    接口 —— 一种辐射式设计(一种行为规范)

    1 [public] interface InterfaceName {
    2 
    3 }
    • 接口 本身不是类 
    • 变量  被隐式地指定为public static final (只能是public static final变量,用private修饰会报编译错误)
    • 方法【必须都抽象方法】  被隐式地指定为public abstract (只能是public abstract方法) 
    • 接口中所有的方法不能有具体的实现

    接口是一种极度抽象的类型,比抽象类更加“抽象”,并且一般情况下不在接口中定义变量

    对比 —— 

    语法层面上的区别

      1)抽象类可以提供成员方法的实现细节,而接口中只能存在public abstract 方法;

      2)抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型的;

      3)接口中不能含有静态代码块以及静态方法,而抽象类可以有静态代码块和静态方法;

      4)一个类只能继承一个抽象类,而一个类却可以实现多个接口。

    设计层面上的区别

    1. 什么是模板式设计?例子:用模板A设计了ppt B和ppt C,ppt B和ppt C公共的部分就是模板A,如果公共部分需要改动,则只需要改动模板A就可以了,不需要重新对ppt B和ppt C进行改动
    2. 什么是辐射式设计?比如某个电梯都装了某种报警器,一旦要更新报警器,就必须全部更新。

    抽象类是自底向上抽象而来的,接口是自顶向下设计出来的 

    • 对于抽象类,如果需要添加新的方法,可以直接在抽象类中添加具体的实现,子类可以不进行变更;
    • 而对于接口则不行,如果接口进行了变更,则所有实现这个接口的类都必须进行相应的改动。

    实例 —— 

    看一个网上流传最广泛的例子:门和警报的例子:门都有open( )和close( )两个动作,此时我们可以定义通过抽象类和接口来定义这个抽象概念:

    1 abstract class Door {
    2     public abstract void open();
    3     public abstract void close();
    4 }

    或者:

    1 interface Door {
    2     public abstract void open();
    3     public abstract void close();
    4 }

      这种方法违反了面向对象设计中的一个核心原则ISP (Interface Segregation Principle)【见批注】,在Door的定义中把Door概念本身固有的行为方法和另外一个概念"报警器"的行为方 法混在了一起。这样引起的一个问题是那些仅仅依赖于Door这个概念的模块会因为"报警器"这个概念的改变而改变,反之依然。

    Door的open() 、close()和alarm()根本就属于两个不同范畴内的行为,open()和close()属于门本身固有的行为特性,而alarm()属于延伸的附加行为。因此最好的解决办法是单独将报警设计为一个接口,包含alarm()行为,Door设计为单独的一个抽象类,包含open和close两种行为。再设计一个报警门继承Door类和实现Alarm接口。

     1 interface Alram {
     2     void alarm();
     3 }
     4  
     5 abstract class Door {
     6     void open();
     7     void close();
     8 }
     9  
    10 class AlarmDoor extends Door implements Alarm {
    11     void oepn(){
    12       //....
    13     }
    14     void close(){
    15       //....
    16     }
    17     void alarm(){
    18       //....
    19     }
    20 }

     

    批注: 

            ISP(Interface Segregation Principle接口分离原则):面向对象的一个核心原则。它表明使用多个专门的接口比使用单一的总接口要好。

           一个类对另外一个类的依赖性应当是建立在最小的接口上的。

           一个接口代表一个角色,不应当将不同的角色都交给一个接口。没有关系的接口合并在一起,形成一个臃肿的大接口,这是对角色和接口的污染。

  • 相关阅读:
    .NET的JSNO 序列化跟反序列化
    SQL Server 查询分析器提供的所有键盘快捷方式(转)
    SQL Server 中WITH (NOLOCK)浅析(转潇湘隐者)
    Microsoft Dynamics CRM 2011的组织服务中的RetrieveMultiple方法(转)
    C#对多个集合和数组的操作(合并,去重,判断)
    Silverlight Telerik控件学习:主题Theme切换html教程
    VMware 11安装Mac OS X 10.10
    Android 下载网络图片注意的问题
    对下载文件是否完整的判断方法
    Android实现通用的ActivityGroup(效果类似Android微博客户端主界面),强烈建议不要再使用TabActivity
  • 原文地址:https://www.cnblogs.com/JARVISAI/p/7582039.html
Copyright © 2020-2023  润新知