一、复用
1.复用种类:
白盒复用:源代码可见,复制已有代码到正在开发的系统,进行修改和扩展
黑盒复用:源代码不可见,不能修改,只能通过API接口来使用
1)源码级别复用
2)模块级别复用:类,接口
i)复用类的方法:,继承,委托
委托:当一个对象依赖另一个对象的一些子功能时
3)库级别复用
2.设计复用类in oop
二、行为子类型和LSP
1)子类型多态:客户端可以用统一的方式处理不同类型的对象
如果对于类型T的对象x,q(x)成立,那么对应于类型T的子类型S的对象y,q(y)也成立。
2)子类型中可以增加方法,但不可以删除方法
3)具体类必须实现抽象类型中所有未实现的方法
4)子类型中override的方法的返回值必须是相同类型或其原类型的子类型或者符合co-variant参数
5)子类型中重写的方法必须使用同样类型的参数或者符合contra-variant的参数(但java不支持)
6)子类型中重写的方法必须不能抛出额外的异常
7)也适用于具体的行为(方法):相同或更强(额外增加)的不变量
相同或更弱的前置条件
相同或更强的后置条件
三、LSP(Liskov Substitution Principle)liskov 替代原则
1.行为子类型:
1)子类型多态:客户端可以用统一的方式处理不同类型的对象
2)如果对于类型T的对象x,q(x)成立,那么对于类型T的子类型S的对象y,q(y)也成立
如果一个类a是另一个类b的子类型,那么一个表达式中的的类型b可以在被任何时候被替换为a
3)静态类型检查的原则:
子类型可以增加方法,但不可以删。
子类型需要实现抽象类型(接口,抽象类)的所有未实现的方法
子类型中重写的方法的返回值必须相同或是子类型或者符合 co-variant的参数
子类型中重写的方法必须使用同样类型的参数或者符合cotra-variant的参数(此种情况java目前按照重载overload处理)
子类型中overriding方法不能抛出额外的异常
更强的不变量
更弱的前置条件
更强的后置条件
1.LSP:是一个特定的子类型关系定义,被称为强行为子类型化
在编程语言中,LSP依赖于下列限制:
1)前置条件不能强化
2)后置条件不能弱化
3)不变量要保持
4)子类型方法参数:逆变
5)子类型方法返回值:协变
6)异常类型:协变
2.协变:父类型->子类型:越来越具体,返回值类型:不变或变得更具体,异常类型too
3.反协变:父类型->子类型:越来越具体,参数类型:要相反的变化,要不变或越来越抽象
但这种行为在java中不允许,会被当做overload看待
参数类型协变会造成类型不安全
3.1在java中,对于T[]数组,可以保存类型T及其子类型的数据
4.泛型中的LSP:
泛型是类型不变的,例如:List<String> is not a subtype of List<Object> ArrayList is a subtype of List<String>
类型参数在编译后被丢弃,运行时不可用。称之为类型擦除
5.虚拟机中没有泛型类型对象:所有对象都属于普通类,泛型信息只存在于编译阶段,在运行时会被擦除;定义泛型类型时,会自动提供一个对应的原始类型(非泛型类型),原始类型的名字就是去掉参数类型后的泛型类型名。擦除时类型变量会被擦除,替换为限定类型,如果没有限定类型则替换为Object类型。
6.类型擦除
类型参数有限定时,可以调用类型相关的具体方法。
有多个限定时,用第一个
运行时类型查询只适用于原始类型。
instanceof 比较的是继承关系或者实现关系的类类型,子类对象或者实现类对象放在前面;而getClass得到的是确切的类型,并不考虑继承,它判断的是引用指向的对象的类型,与声明该变量的类型无关。
myclass<A> and myclass<B>没什么关系
可以用通配符实现两个泛型类的协变
无限定通配符:?
情况1:方法的实现不依赖于类型参数(不调用其中的方法),如List中的 方法;
情况2:或者只依赖于Object 类中的功能
无限定通配符,一般用于定义一个引用变量,其可以指向多个不同类型的变量;
若不用?,用固定类型
限定的类型参数允许调用限定类型中的方法。
确保src是dest的子类
三、Delegation and Composition
1.如果你的ADT需要比较大小,或者要放入Collections或Arrays中进行排序,可实现Comparator接口并override compare()函数。
委托:一个对象请求另一个对象的部分功能
委托是复用的一种常见形式
委托与继承之间的选择:
1.使用委托:如果子类只需要复用父类中的一小部分方法。创建一个包含父类对象的域,用次对象委托方法。
一个类不需要继承另一个类的全部方阿飞,通过委托机制调用部分方法,从而避免继承大量无用方法。
CRP原则:composite over inheritance principle 组合优先于继承
“委托” 发生在object层面,而“继承”发生在class层面
接口的组合
五、委托的类型
1)dependency临时性的委托:通过方法的参数或者在方法的局部中使用发生联系。
2)association永久性的委托:通过在类中设置一个域。
3)composition 更强的association
4)aggregation:更弱的association 可以动态变化
summary:
dependency: A use one or multiple B;
ASSOCIATION: A has one or multiple B;
composition/aggregation(A owns one or multiple B)
六、白盒和黑盒框架
1)白盒框架: 通过子类型和重写方法实现扩展
普遍设计模式:模板方法
子类有主方法但是给控制于框架
2)黑盒框架:通过实现一个插件接口扩展
普遍设计模式:策略,观察器
插件加载机制加载插件并且给控制于框架