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

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

第二节:复用性的实施

问题一:设计可复用的类

1.行为子类型和LSP原则

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

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

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

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

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

父类:


子类:


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

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

次父类:


子类:


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

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

    要求:

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

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

    1. 协变Covariance

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

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

    异常的类型:也是如此。

例:



    2.  反协变、逆变Contravariance

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

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

例:


    3.总结协变与逆变


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

问题三:各种应用中的LSP

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

   

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

2.泛型中的LSP

  • ***

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

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

(所以,泛型不是协变)

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




  • 总结泛型中的LSP

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

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


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

    1.更低边界的通配符:

    2.更高边界的通配符:

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

  •     List<Number> is a subtype of List<?>
  •     List<Number> is a subtype of List<? extends Object>
  •     List<Object> is a subtype of List<? super String>


问题四:委派(Delegation)(复用的一种常见形式)

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

*例:继承与委派的对比



    委派的类型:

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

    模型:


①Use--临时性的delegation


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

②Association--永久性的delegation


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

③Composition--更强的delegation

 


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

④Aggregation


2.委派使用的情况

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

问题五:组合(Composition)

    CRP原则:Composite Reuse Principle

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

继承:

父类:


子类:


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

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

组合:(CRP)


更为一般的委派的设计:


**:对比继承和 组合

继承:


组合:


问题六:两种模型

1.


2.



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值