2 Inheritance & DBC Our previous treatment of DBC ignored inheritance Now that you’ve had time to internalize DBC, let’s throw inheritance into the mix DBC leads to a better understanding of inheritance, and helps us apply it more effectively
3 Inheritance & DBC Client A R INV A PRE A.R POST A.R A a = new A(); a.R();
4 Inheritance & DBC Client A R INV A PRE A.R POST A.R B R INV B PRE B.R POST B.R ? A a = new B(); a.R();
5 Inheritance & DBC Conceptually, B’s implementation must honor A’s contract; otherwise, clients will break when using a B instead of an A B can provide a “better” implementation than A, but not a “worse” one What do “better” and “worse” mean? –Square root exampleSquare root example
6 Subclasses can be less strict, but not more strict B can be less strict on clients than A, but not more strict B can weaken R’s pre-conditions –PRE B.R can place fewer requirements on clients than PRE A.R, but not more –PRE B.R <= PRE A.R –PRE A.R logically implies PRE B.R
7 Subclasses can do more, but not less B’s behavior must be consistent with A’s contract B can do better than A, but not worse B can strengthen R’s post-conditions, but not weaken –POST B.R can promise more to clients than POST A.R, but not less –POST B.R >= POST A.R –POST B.R logically implies POST A.R B can strengthen A’s class invariants, but not weaken –INV B can promise more to clients than INV A, but not less –INV B >= INV A –INV B logically implies INV A
8 Another example Stack example
9 Liskov Substitution Principle Let q(x) be a property provable about objects x of type T. Then q(y) should be true for objects y of type S where S is a subtype of T.