可复用性
┉┉∞ ∞┉┉┉┉∞ ∞┉┉┉∞ ∞┉┉
行为子结构
对于父子的继承关系的要求:
·子类可以增加方法,但不可以删
·子类需实现抽象类型中未实现的方法
·子类重写(override)的方法必须有相同的返回值和参数列表
·子类不能抛出额外的异常
对于具体的方法:
·更强的不变量
·更弱的前置条件
·更强的后置条件
┉┉∞ ∞┉┉┉┉∞ ∞┉┉┉∞ ∞┉┉
协变与逆变
协变:从父类型到子类型,返回值或异常的类型不变或变得更具体
逆变:从父类型到子类型,参数变得越来越抽象(不允许)
不变:只是重写了方法
┉┉∞ ∞┉┉┉┉∞ ∞┉┉┉∞ ∞┉┉
【LSP】
子类可以扩展父类的功能,但不能修改父类原有的功能
子类可以有自己的个性
子类覆盖或实现父类的方法时输入参数可以变抽象,返回值变具体
(留坑)
┉┉∞ ∞┉┉┉┉∞ ∞┉┉┉∞ ∞┉┉
子类只需要复用父类中的一小部分方法,可以不需要通过继承,而通过委派来完成
组合的例子:
对于不同的子类对象,委派能计算它的奖金的方法,就不需要在子类继承的时候每个子类里都进行重写
┉┉∞ ∞┉┉┉┉∞ ∞┉┉┉∞ ∞┉┉┉┉∞ ∞┉┉┉┉∞ ∞┉┉┉∞ ∞┉┉
【可复用的设计模式】
- 结构型模式:Structural patterns
- 适配器模式(Adapter)
- 装饰器模式(Decorator )
- 外观模式(Facade)
- 行为类模式:Behavioral patterns
- 策略模式(Strategy)
- 模板方法模式(Template method)
- 迭代器模式( Iterator)
┉┉∞ ∞┉┉┉┉∞ ∞┉┉┉∞ ∞┉┉
结构型模式:
适配器模式 Adaptor
增加一个接口,将已存在的子类封装起来,client面向接口编程
装饰器模式 Decorator
替代继承,向一个现有的类中添加新的功能
这种模式创建了一个装饰类,用来包装原有的类
Stack s = new ArrayStack(); //构建一个普通的堆栈 UndoStack s = new UndoStack(new ArrayStack()); //构建撤消堆栈 SecureStack s = new SecureStack( new SynchronizedStack( new UndoStack(s)))//构建安全的同步撤消堆栈
这样一层层的实现就是Decorator模式
外观模式 Facade
提供一个统一的接口来代替小接口的调用,相当于对复杂系统做了封装,供客户端简洁的使用
┉┉∞ ∞┉┉┉┉∞ ∞┉┉┉∞ ∞┉┉
行为型模式:
策略模式 Strategy
创建表示各种模式的对象和一个行为随着不同对象策略而改变的context,策略对象改变context执行的算法
public interface AStrategy { public abstract a(); } // 一个策略对象 public class B implements AStrategy { // 还可以有 C D 等等不同的策略对象 // fields // Constructor @Override public double a() { // 不同的策略对象这里不一样 } } public class AContext { public double a(AStrategy aStrategy) { return aStrategy.a(); } } public class Main { AContext context = new AContext(); double ans = context.a(new AStrategy() {}); }
模板模式 Template
抽象类定义执行它的方法/模式,子类按照需要重写方法,但调用以抽象类中的方法调用
public abstract class Edge { // fields public abstract boolean a(); } public class DirectedEdge extends Edge { // different fields //constructor @Override public boolean a() { // method } }
迭代器模式 Iterator
顺序访问集合对象中的元素,又不暴露对象的内部表示
让集合类实现Iterable接口,重写 next(), hasNext(), remove()