第五章--第二节:复用性的实施

第五章:面向软件构造的可复用性的构建方法

第二节:复用性的实施

问题一:设计可复用的类

1.行为子类型和LSP原则

    子类型多态:客户端可用统一的方式处理不同类型的对象

    子类型多态要遵守的原则:

  • 客户端可用统一的方式处理不同类型的对象
  • 子类型需要实现抽象类型中的所有未实现方法
  • 子类型中重写的方法必须有相同或子类型的返回值
  • 子类型中重写的方法必须使用同样类型的参数
  • 子类型中重写的方法不能抛出额外的异常

    方法中的LSP原则:更强的不变量、更弱的前置条件、更强的后置条件

**例:看下列子类是否满足LSP原则

父类:

第五章--第二节:复用性的实施_第1张图片

子类:

第五章--第二节:复用性的实施_第2张图片

(解:子类具有和父类一样的表示不变量,并且有额外的表示不变量,表示不变量没有变弱;并且重写的方法有相同的前置和后置条件,满足LSP)

**:看下列子类是否满足LSP原则

次父类:

第五章--第二节:复用性的实施_第3张图片

子类:

第五章--第二节:复用性的实施_第4张图片

(解:次父类的)**********************

2.LSP是一种对子类型关系的特殊的定义,被称为 强行为子类化

    要求:

  • 前置条件不能强化
  • 后置条件不能弱化
  • 不变量要保持
  • 子类型方法参数:逆变
  • 子类型方法的返回值:协变

问题二:Covariance (协变) 与 Contravariance (反协变、逆变)

    1. 协变Covariance

    父类型-->子类型:越来越具体specific

    返回值类型:不变或变得更具体

    异常的类型:也是如此。

例:

第五章--第二节:复用性的实施_第5张图片

第五章--第二节:复用性的实施_第6张图片

    2.  反协变、逆变Contravariance

    父类型-->子类型:越来越具体specific

    参数类型:要相反的变化,要不变或越来越抽象

例:

第五章--第二节:复用性的实施_第7张图片

    3.总结协变与逆变

第五章--第二节:复用性的实施_第8张图片

(1.子类型(属性、方法)关系;2.不变性,重写方法;3.协变,方法返回值变具体;4.逆变,方法参数变抽象;5.协变,参数变的更具体,协变不安全)

问题三:各种应用中的LSP

1.数组中协变(数组是协变的)

    第五章--第二节:复用性的实施_第9张图片

(在java的子类型规则中,一个T类型的数组,其中包含的元素可以是T类型也可以是T的子类型)

2.泛型中的LSP

  • ***

(注意:第一行符合子类型关系,而第二行不符合子类型关系)

(原因:因为在泛型中存在 类型擦出(type erasure))

(所以,泛型不是协变)

:???????????????

第五章--第二节:复用性的实施_第10张图片

第五章--第二节:复用性的实施_第11张图片

第五章--第二节:复用性的实施_第12张图片

  • 总结泛型中的LSP

第五章--第二节:复用性的实施_第13张图片

尽管Integer是Number的子类型,但Box也不是Box的子类型

3.为了解决类型擦除的问题-----Wildcards(通配符)


(?是一种不确定的类型)

    1.更低边界的通配符:

    2.更高边界的通配符:

    3.带有通配符的泛型的LSP:

  •     List is a subtype of List
  •     List is a subtype of List
  •     List is a subtype of List
  • 第五章--第二节:复用性的实施_第14张图片
  • 第五章--第二节:复用性的实施_第15张图片
  • 问题四:委派(Delegation)(复用的一种常见形式)

        1.委派:一个对象请求另一个对象的功能(“委托”发生在objet层面,而“继承”发生在class层面)

    *例:继承与委派的对比

    第五章--第二节:复用性的实施_第16张图片


        委派的类型:

    • Use(A use B) 
    • Composition/aggregation (A owns B)
    • Association (A has B)

        模型:

    第五章--第二节:复用性的实施_第17张图片

    ①Use--临时性的delegation

    第五章--第二节:复用性的实施_第18张图片

    (直接在方法中委托其他类的对象,只是使用的其他类的对象,是临时的)

    ②Association--永久性的delegation


    (一个类有其他类的对象声明(has),是永久性的)

    ③Composition--更强的delegation

     

    第五章--第二节:复用性的实施_第19张图片

    (一个类有另一个类的对象声明(is part of),更是永久性的)

    ④Aggregation

    第五章--第二节:复用性的实施_第20张图片

    2.委派使用的情况

    •   如果子类只需要复用父类中的一小部分方法
    •   一个类不需要继承另一个类的全部方法,通过委托机制调用部分方法

    问题五:组合(Composition)

        CRP原则:Composite Reuse Principle

    **:一个公司要分红,但公司不同职位(经理、程序员、秘书)的分红不同(用继承和组合机制对比实现)

    继承:

    父类:


    子类:

    第五章--第二节:复用性的实施_第21张图片

    (但不同的人分红不同,所以每种职位都要重写父类中的方法,代码很赘余)

    (核心问题:每个Employee对象的奖金计算方法都不同,在object层面而非class层面。)

    组合:(CRP)

    第五章--第二节:复用性的实施_第22张图片

    更为一般的委派的设计:

    第五章--第二节:复用性的实施_第23张图片


    **:对比继承和 组合

    继承:

    第五章--第二节:复用性的实施_第24张图片

    组合:

    第五章--第二节:复用性的实施_第25张图片

    问题六:两种模型

    1.

    第五章--第二节:复用性的实施_第26张图片

    2.

    第五章--第二节:复用性的实施_第27张图片


    你可能感兴趣的:(第五章--第二节:复用性的实施)