CSC 517: Elegance and Inheritance, Part I Titus Barik ([email protected]) Spring 2014.

32
CSC 517: Elegance and Inheritance, Part I Titus Barik ([email protected]) Spring 2014

Transcript of CSC 517: Elegance and Inheritance, Part I Titus Barik ([email protected]) Spring 2014.

Page 1: CSC 517: Elegance and Inheritance, Part I Titus Barik (tbarik@ncsu.edu) Spring 2014.

CSC 517: Elegance and Inheritance, Part I

Titus Barik ([email protected])Spring 2014

Page 2: CSC 517: Elegance and Inheritance, Part I Titus Barik (tbarik@ncsu.edu) Spring 2014.

Theory vs. Practice

• “I want to move to theory. Everything works in theory.” (John Cash)

• “Well, it may be all right in practice, but it will never work in theory.” (Warren Buffett)

Page 3: CSC 517: Elegance and Inheritance, Part I Titus Barik (tbarik@ncsu.edu) Spring 2014.

Multiple Inheritance

• Diamond problem: Which method is called first?

• How can we handle this problem?

• Class D extends B, C

B C

A

D

Page 4: CSC 517: Elegance and Inheritance, Part I Titus Barik (tbarik@ncsu.edu) Spring 2014.

Multiple Inheritance

• Exercise: Scala resolves method names using right-first depth-first search. Reduce all but last when redundancy occurs.

• Answer: – [D, C, A, B, A] which reduces to– [D, C, B, A]

• What is printed with the given trait?

Page 5: CSC 517: Elegance and Inheritance, Part I Titus Barik (tbarik@ncsu.edu) Spring 2014.

C3 Linearization (Perl, Python)

1. Consistent extended precedence graph.

2. Local precedence order.3. Monotonicity

L[C(B1,B2,…,BN)] = [C] + merge(L[B1],…,L[BN], B1…BN)

Source: Barnett, et. al. A Monotonic Superclass Linearization for Dylan, 1996.

Page 6: CSC 517: Elegance and Inheritance, Part I Titus Barik (tbarik@ncsu.edu) Spring 2014.

Merge Pre-requisites

• head(C1C2C3) = C1

• tail(C1C2C3) = C2C3

• C + C1C2C3 = CC1C2C3

(concatenation)

Page 7: CSC 517: Elegance and Inheritance, Part I Titus Barik (tbarik@ncsu.edu) Spring 2014.

Merge Operation

Example: merge(DO, EO, DE)

•The merge of several sequences is a sequence that contains each of the elements of the input sequences.•An element that appears in more than one of the input sequences appears only once in the output sequence.•If two elements appear in the same input sequence, their order in the output sequence is the same as their order in the input sequence.

Page 8: CSC 517: Elegance and Inheritance, Part I Titus Barik (tbarik@ncsu.edu) Spring 2014.

Merge Example, 1

• Class B extends D, E

• Class C extends D, F

• Class A extends B, C

E

O

DF

C B

A

Page 9: CSC 517: Elegance and Inheritance, Part I Titus Barik (tbarik@ncsu.edu) Spring 2014.

Merge Example, 2

L[C(B1,B2,…,BN)] = [C] +

merge(L[B1],…,L[BN], B1…BN)

L[O] = O

L[D] = D + merge(O, O) = DO

L[E] = E + merge(O, O) = EO

L[F] = F + merge(O, O) = FO

L[B] = B + merge(DO, EO, DE)

= B + DEO = BDEO

E

O

DF

C B

AMerge results

Page 10: CSC 517: Elegance and Inheritance, Part I Titus Barik (tbarik@ncsu.edu) Spring 2014.

Merge Example, 3L[C(B1,B2,…,BN)] = [C] + merge(L[B1],…,L[BN], B1…BN)

L[B] = B + merge(DO, EO, DE) = B + DEO = BDEO

L[C] = C + merge(DO, FO, DF) = C + DFO = CDFO

L[A] = A + merge(BDEO, CDFO, BC) = A + BCDEFO = ABCDEFO

E

O

DF

C B

A

Page 11: CSC 517: Elegance and Inheritance, Part I Titus Barik (tbarik@ncsu.edu) Spring 2014.

Polymorphism

• Unbounded polymorphism. Is there an example of a language that has this?

• Java uses subtype polymorphism.• Categorizations: bounded and

dynamic (inheritance), unbounded and static (templates).

Page 12: CSC 517: Elegance and Inheritance, Part I Titus Barik (tbarik@ncsu.edu) Spring 2014.

Dynamic Method Invocation

• Dynamic method invocation means that the JVM, when asked to invoke a method on an object, looks at the actual class (versus declared) of the object to find the method to execute.

• Dynamic binding or late binding.• Can’t override this in Java.

Page 13: CSC 517: Elegance and Inheritance, Part I Titus Barik (tbarik@ncsu.edu) Spring 2014.

Overloading vs. Overriding

• Two methods with the same name are overloaded if they are in the same class*, but have different parameter lists.

• When a method is overridden, one of its subclasses declares a method of the same name, with the same signature.

Page 14: CSC 517: Elegance and Inheritance, Part I Titus Barik (tbarik@ncsu.edu) Spring 2014.

A Fruity Example

• Fruit inherits from class Object.• Object: boolean equals(Object obj).• Fruit: boolean equals(Fruit fruit).• Is this overriding or overloading?

Page 15: CSC 517: Elegance and Inheritance, Part I Titus Barik (tbarik@ncsu.edu) Spring 2014.

A Fruity Example

Object o = new Object();Fruit f = new Fruit();Object of = new Fruit();

f.equals(o);(calls object)f.equals(f); (calls fruit)f.equals(of);(calls object)

Page 16: CSC 517: Elegance and Inheritance, Part I Titus Barik (tbarik@ncsu.edu) Spring 2014.

What about now?

o.equals(o);

o.equals(f);

o.equals(of);

of.equals(o);

of.equals(f); // tricky tricky

of.equals(of);

Page 17: CSC 517: Elegance and Inheritance, Part I Titus Barik (tbarik@ncsu.edu) Spring 2014.

Last One

• One more change:– Add boolean equals(Object obj)to

Fruit.

• Now what? Panic?Fruit Object Fruit (Object)

f.equals(o) o.equals(o) of.equals(o)

f.equals(f) o.equals(f) of.equals(f)

f.equals(of) o.equals(of) of.equals(of)

Page 18: CSC 517: Elegance and Inheritance, Part I Titus Barik (tbarik@ncsu.edu) Spring 2014.

Invocation Summary

• The compiler decides which overloaded method to call by looking at – the declared types of the arguments

• And at runtime:– binding to the most specialized object

(actual type) that can receive the message through dynamic method invocation.

• In Java, dynamic binding always occurs. You can’t bypass it, even with casting.

Page 19: CSC 517: Elegance and Inheritance, Part I Titus Barik (tbarik@ncsu.edu) Spring 2014.

Ice Cream and Cake and Cake

• What is the object-oriented way of getting rich?

• Inheritance.

Page 20: CSC 517: Elegance and Inheritance, Part I Titus Barik (tbarik@ncsu.edu) Spring 2014.

Interfaces

• Java (and C#) don’t have multiple inheritance, but how can we simulate it?

• “Program to an interface, not an implementation.” (GoF)

• Which is preferred:– ArrayList list = new ArrayList();– List list = new ArrayList();

Page 21: CSC 517: Elegance and Inheritance, Part I Titus Barik (tbarik@ncsu.edu) Spring 2014.

Generics

• Even better:– ArrayList list = new ArrayList<Shape>();

• How do generics help us?– Shape s = new Shape();– list.add(s);– Shape q = List.get(0)

• Generics allow us to statically communicate type information to the compiler; use them everywhere.

Page 22: CSC 517: Elegance and Inheritance, Part I Titus Barik (tbarik@ncsu.edu) Spring 2014.

Inheritance is tricky.

• We have done examples with inheritance, but when should it be used?

• Is Y an X? What does it mean for Y to be an X? (is-a relationship).

• Temptations:– Code reuse.– Subclassing for specializing.– Public interface.– Polymorphism (collections).

• In theory, this is great. But is it sufficient? Is it even a good reason?

Page 23: CSC 517: Elegance and Inheritance, Part I Titus Barik (tbarik@ncsu.edu) Spring 2014.

Inheritance is overused.

• When all you have is a hammer, everything you see is a nail.

• What about the code reuse example?• Inheritance breaks encapsulation.

Why?• Favor composition over class

inheritance.

Page 24: CSC 517: Elegance and Inheritance, Part I Titus Barik (tbarik@ncsu.edu) Spring 2014.

Is a Square a Rectangle?

Page 25: CSC 517: Elegance and Inheritance, Part I Titus Barik (tbarik@ncsu.edu) Spring 2014.

Is a Square a Rectangle?

Class Rectangle {

private int width, height;

public

Rectangle(int w, int h);

public int getWidth();

public setWidth(int width);

...

public setSize(int w, int h);

}

http://www.objectmentor.com/resources/articles/lsp.pdf

Page 26: CSC 517: Elegance and Inheritance, Part I Titus Barik (tbarik@ncsu.edu) Spring 2014.

Uh-oh Spaghettios

• Constructor: Square(int s);• setSize(int w, int h)

– Let’s remove it, but derived classes requiring changes to base classes already indicates a bad design.

• setHeight(5) => changes width.– Are we now okay?

• r.getWidth() * r.getHeight()

Validity is not instrinsic and cannot be viewed in isolation.

A square is a rectangle, but a square object is not a rectangle object.

Page 27: CSC 517: Elegance and Inheritance, Part I Titus Barik (tbarik@ncsu.edu) Spring 2014.

Inheritance Formalization

• Liskov substitution principle, easy in theory, difficult in practice to get right.

• 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.

• You’re probably thinking: “I hope this isn ’t on the exam.”

• But you would be wrong.

Page 28: CSC 517: Elegance and Inheritance, Part I Titus Barik (tbarik@ncsu.edu) Spring 2014.

Direct From the Java API

• Remember code reuse? Inheritance is all or nothing.• “Because Properties inherits from Hashtable, the

put and putAll methods can be applied to a Properties object. Their use is strongly discouraged as they allow the caller to insert entries whose keys or values are not Strings. The setProperty method should be used instead. If the store or save method is called on a “compromised” Properties object that contains a non-String key or value, the call will fail.”

• Didn’t you get the memo?• Yeah. I got the memo. And I understand the policy.

And the problem is just that I forgot the one time. And I've already taken care of it so it's not even really a problem anymore.

Page 29: CSC 517: Elegance and Inheritance, Part I Titus Barik (tbarik@ncsu.edu) Spring 2014.

Real-World Violations of LSP

• In practice*:– Java violates LSP (unmodifiableList).– Ruby violates LSP (dup method).– C# probably violates LSP.

Page 30: CSC 517: Elegance and Inheritance, Part I Titus Barik (tbarik@ncsu.edu) Spring 2014.

Ruby Example

irb> 5.respond_to? :dup

=> true

irb> 5.dup

TypeError: can't dup Fixnum

from (irb):1:in `dup'

from (irb):1

•And I would have gotten away with it too, if it weren't for you meddling kids…

Page 31: CSC 517: Elegance and Inheritance, Part I Titus Barik (tbarik@ncsu.edu) Spring 2014.

Real-World Violations of LSP?

• Workarounds:– Java fine print: “Returns an unmodifiable view of the specified

list. This method allows modules to provide users with "read-only" access to internal lists. Query operations on the returned list "read through" to the specified list, and attempts to modify the returned list, whether direct or

via its iterator, result in an UnsupportedOperationException. “– Ruby dup method (found in Object). It’s

dynamic, get over it. We don’t have a contract.

– C# workaround is to seal everything, but this breaks the open-closed principle.

Page 32: CSC 517: Elegance and Inheritance, Part I Titus Barik (tbarik@ncsu.edu) Spring 2014.