zoukankan      html  css  js  c++  java
  • 面向对象的特征

    (1)封装变化点

    找出应用中可能需要变化之处,把它们独立出来,不要和那些不变化的代码混淆在一起。即,把会变化的部分抽取并封装起来,方便以后改动或扩充,而不影响不需要变化的部分。

    封装变化点是面向对象中总的原则,针对接口编程是实现方式,

    方式:一般通过将抽象出变化点的共同接口(接口或者抽象基类),将变化点实现为共同接口的子类;不变点与变化点通过继承和组合两种方式关联起来,共同组成一个完整的对象。

    (2)针对接口编程,而不是针对实现编程

    接口,主要作用是定义一个行为规范。所有实现该接口的超类都必须实现接口定义的规范。对接口赋予不同的超类,即可实现不同的操作,实现了“求同存异”。

    这里的接口,可以包括两个方式,接口与抽象基类。接口与抽象基类的共性和个性参考

    抽象基类与接口,共性与个性的选择

    抽象基类(Abstract Class)和接口(Interface)都实现了面向对象中的继承机制,它们通过定义方法签名匀实现了对继承类的功能上的约束。下面对比二者在C#中的异同。

    相同点

    • 都可以被继承。
    • 本身都不能被实例化

    不同点

    • 抽象类是一个不完整的类,需要进一步细化;而接口只是一个行为上的规范。
    • 抽象基类不能实现多继承,而接口可以实现多继承。
    • 抽象基类可以定义字段、属性、包含有实现的方法。接口可以定义字段、索引器、事件但不能定义字段和包含实现的方法。     

    共性、个性与选择

    有的书上写到C#中推荐使用接口(Interface)来替代抽象基类(Abstract Class), 并强调使用接口的诸多好处,这点我不敢苟同,从上面列表中看来,两者之间还是存在不少差异的,而这种差异的存在性必然决定了适用场景的不同,例如在抽象基 类中可以为部分方法提供默认的实现,从而避免在子类中重复实现它们,提高代码的可重用性,这是抽象类的优势所在;而接口中只能包含抽象方法。至于何时使用抽象基类何时使用接口关键还是取决于用户是如何看待继承类之间的联系的,用户更加关心的是它们之间的个性差异还是它们之间的共性联系。接口更加强调 了继承对象间具有相同的行为,而抽象类同时还强调了继承对象间具有相同的属性。而真正将接口与抽象基类区分开的则是理由一,归纳如下:

    1. 当在差异较大的对象间寻求功能上的共性时,使用接口。
    2. 当在共性较多的对象间寻求功能上的差异时,使用抽象基类。

    抽象类和接口区别总结

     1、类是对对象的抽象,可以把抽象类理解为把类当作对象,抽象成的类
       接口只是一个行为的规范或规定,微软的自定义接口总是后带able字段,证明其是表述一类类“我能做。。。”。

           抽象类更多的是定义在一系列紧密相关的类间,而接口大多数是关系疏松但都实现某一功能的类中。 
     2、接口基本上不具备继承的任何具体特点,它仅仅承诺了能够调用的方法;
     3、一个类一次可以实现若干个接口,但是只能扩展一个父类
     4、接口可以用于支持回调,而继承并不具备这个特点
     5、抽象类不能被密封
     6、抽象类实现的具体方法默认为虚的,但实现接口的类中的接口方法却默认为非虚的,当然您也可以声明为虚的。
     7、接口与非抽象类类似,抽象类也必须为在该类的基类列表中列出的接口的所有成员提供它自己的实现。但是,允许抽象类将接口方法映射到抽象方法上
     8、抽象类实现了oop中的一个原则,即:把可变的与不可变的分离。抽象类和接口就是定义为不可变的,而把可变的作为子类去实现。 
     9、.好的接口定义应该是具有专一功能性的,而不是多功能的,否则造成接口污染。如果一个类只是实现了这个接口的中一个功能,而不得不去实现接口中的其他方法,就叫接口污染。 
     10、尽量避免使用继承来实现组建功能,而是使用黑箱复用,即对象组合。因为继承的层次增多,造成最直接的后果就是当你调用这个类群中某一类,就必须把他们全部加载到栈中!后果可想而知。
     11、• 如果抽象类实现接口,则可以把接口中方法映射到抽象类中作为抽象方法而不必实现,而在抽象类的子类中实现接口的方法;
       • 如果预计要创建组件的多个版本,则创建抽象类。抽象类提供简单的方法来控制组件版本。
       • 如果创建的功能将在大范围的全异对象间使用,则使用接口。
       • 如果要设计小而简练的功能块,则使用接口。如果要设计大的功能单元,则使用抽象类。  
       • 如果要在组件的所有实现间提供通用的已实现功能,则使用抽象类。

    =================================================================================

    抽象类:
      a.包含一个或多个抽象方法或属性的类必须定义为抽象类
      b.继承抽象类的派生类必须实现抽象类的所有抽象方法或属性,否則該派生类也必是抽象类,至到完全实现为止.
      c.抽象类必须是公共的(public).
      d.抽象类不存在对象实例,但可以申明引用变量.另外抽象类中可以有非抽象方法,供派生类调用.

    接 口:
      1.接口中定义抽象的方法,属性,索引,事件
      2.接口必须由类來实现,故其只能是默认public的,不可顯式申明,不能申明为 static
      3.实现接口的类必须完全实现接口中的所有的方法属性,索引,事件,不能只实现一部分
      4.一个类只能继承一个基类,但可以实现多个接口,其中继承的基类必须放在最前面,然后是接口,它們用逗號分開.

    =================================================================================

    何时用抽象类,何时用接口?

    ※ 如果预计要创建组件的多个版本,则创建抽象类。抽象类提供简单易行的方法来控制组件版本。通过更新基类,所有继承类都随更改自动更新。另一方面,接口一旦创建就不能更改。如果需要接口的新版本,必须创建一个全新的接口。
    ※ 如果创建的功能将在大范围的全异对象间使用,则使用接口。抽象类应主要用于关系密切的对象,而接口最适合为不相关的类提供通用功能。
    ※ 如果要设计小而简练的功能块,则使用接口。如果要设计大的功能单元,则使用抽象类。
    ※ 如果要在组件的所有实现间提供通用的已实现功能,则使用抽象类。抽象类允许部分实现类,而接口不包含任何成员的实现。

    =================================================================================

    1、接口中只能有方法,不能有字段;抽象类中即可以有方法,也可以有属性和字段;
    2、接口中的方法不需要实现,而抽象类中可以有实现了的方法;
    3、接口在一定程度上可以代替多继承。
    4、实现接口,也就意味着必须实现接口中的所有方法。如果继承抽象类的子类还是抽象类,则可以只实现部分方法。
    5、接口和抽象类都不被实例化成对象。


    =================================================================================


     下面针对抽象类和接口做一个详细的对比

    抽象类( abstract method  ) 接口 (  interface  )
    可以包含实现区块 不能包含实现区块
    可以包含抽象方法 不能包含抽象方法
    可以包含非public成员 不可以包含非public成员
    能继承其他的类,包含非抽象类 能继承其他接口
    可以控制版本 无法控制版本
    不能被实例化 不能被实例化

    =================================================================================

    接口用来定义两个对象通信的契约;抽象类用来封装对象间公用的行为。
    二者在设计起初的目标完全不同,可惜在实际应用中被太多的人误解。

    接口 -- 粗略的技术规范
    抽象类 -- 对粗略的技术规范作了一些简单的说明
    类 -- 技术规范的具体实现

    =================================================================================

     (3) 多使用组合,少使用继承

    组合表达的是“有”的概念,继承表达的是“是” 的概念。

    这个原则,其中的原因有以下几点:
    第一、子类对父类的继承是全部的公有和受保护的继承,这使得子类可能继承了对子类无用甚至有害的父类的方法或者数据。换句话说,子类只希望继承父类的一部分方法或者数据,怎么办?
    第二、实际的对象千变万化,如果每一类的对象都有他们自己的类,尽管这些类都继承了他们的父类,但有些时候还是会造成类的无限膨胀。
    第三、 继承的子类,实际上需要编译期确定下来,这满足不了需要在运行内才能确定对象的情况。而组合却可以比继承灵活得多,可以在运行期才决定某个对象。

    第四、对于可以多继承的语言,有可能会带来继承数据或方法冲突的问题,从而造成编译失败。 (例如,A继承B与C,巧合的是,B与C都含有方法D,如果在A中调用D,那么到底是调用哪一个基类的方法呢?)


     
  • 相关阅读:
    剑指offer---尾到头打印链表
    剑指offer---链表中环的入口结点
    剑指offer---删除链表中重复的结点2
    剑指offer---删除链表中重复的结点
    6.shap以及selector的使用
    7.进度条(ProgressBar)
    5.toogleButton以及Switch
    4.基础控件
    3.触摸事件
    2.点击事件和页面切换
  • 原文地址:https://www.cnblogs.com/yue/p/2053801.html
Copyright © 2011-2022 走看看