Top Banner
Implications of Inheritance COMP206, Geoff Holmes and Bernhard Pfahringer
25

Implications of Inheritance COMP206, Geoff Holmes and Bernhard Pfahringer.

Jan 13, 2016

Download

Documents

Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Implications of Inheritance COMP206, Geoff Holmes and Bernhard Pfahringer.

Implications of Inheritance

COMP206, Geoff Holmes and Bernhard Pfahringer

Page 2: Implications of Inheritance COMP206, Geoff Holmes and Bernhard Pfahringer.

Implications OO language must support polymorphic

variables Polymorphic variables: memory

requirements unknown at compile-time => allocated on the heap

Heap allocation => reference semantics for assignment and parameter parsing

Also: equality testing == object identity And: memory management necessary

=> garbage collection (GC)

Page 3: Implications of Inheritance COMP206, Geoff Holmes and Bernhard Pfahringer.

The Polymorphic variable

Squaresidedescribe()

Shapex,ydescribe()

Circleradiusdescribe()

…Shape form = new Circle(10,10,5);form.describe();form = new Square(15,20,10);form.describe();…

Page 4: Implications of Inheritance COMP206, Geoff Holmes and Bernhard Pfahringer.

Memory Layout Stack-based vs. heap-based Stack-based tied to method entry/exit:

Allocate space for all local vars on entry Deallocate on exit Access by numeric offset (activation record) Need to know space requirements at compile-time,

not possible for polymorphic variables! Java: all objects allocated on the heap (new

operator), local vars point to these objects, pointers have a fixed size

Java has no pointers, but internally all object values are represented by pointers.

Page 5: Implications of Inheritance COMP206, Geoff Holmes and Bernhard Pfahringer.

Factorial examplestatic public int factorial(int

n) {int c = n-1;int r;if (c>0)

r = n*factorial(c);else

r = 1;return r;

}

0 n:14 r:18 c:00 n:24 r:?8 c:10 n:34 r:?8 c:2

thirdactivationrecordsecondactivationrecordfirstactivationrecord

Factorial(3)

Page 6: Implications of Inheritance COMP206, Geoff Holmes and Bernhard Pfahringer.

Alternative approach (e.g. C++) Different approaches are possible C++: want to use stack (efficiency) Assignment: extra fields are sliced off,

E.g. a Square is turned into a Shape, Need to distinguish between virtual/non-

virtual methods Need destructors, Pointers/references/values Copy-semantics, …

Page 7: Implications of Inheritance COMP206, Geoff Holmes and Bernhard Pfahringer.

Assignment: reference semanticsBox x = new Box();x.setValue(7);Box y = x;y.setValue(11);System.out.println(x.getValue());System.out.println(y.getValue());…1111 x

a box

y

Simple copy pointer value, i.e. point to same heap-location!

Page 8: Implications of Inheritance COMP206, Geoff Holmes and Bernhard Pfahringer.

Clones If copy desired, must say so, DIY approach:

Box y = new Box();y.setValue(x.getValue());

If common, package into proper method:public Box copy() {

Box b = new Box();b.setValue(getValue());return b;}

Page 9: Implications of Inheritance COMP206, Geoff Holmes and Bernhard Pfahringer.

Clones: Java Class Object provides protected method clone() creating

a bitwise copy of the receiver, plus interface Cloneable Programmer must override clone() to public and

implement Cloneable:

public class Box implements Cloneable { …

public Object clone() {Box b = new Box();b.setValue(getValue());return b;

}}

Use: Box y = (Box) x.clone(); // must cast !!!!

Page 10: Implications of Inheritance COMP206, Geoff Holmes and Bernhard Pfahringer.

Clones: caveats Just a shallow copy, sometimes

need deep copies

x a box a shapey a box

x a box a shape

y a box a shape

SHALLOW

DEEP

Page 11: Implications of Inheritance COMP206, Geoff Holmes and Bernhard Pfahringer.

Parameter passing as assignment Passing a variable considered similar to

assignment, as same value accessible through two different names; pass value, loose some control:static void sneaky (Box b) {b.setValue(11);}…x.setValue(7); sneaky(x); System.out.println(x.getValue());

11

Page 12: Implications of Inheritance COMP206, Geoff Holmes and Bernhard Pfahringer.

Equality test: object identity Easy for primitives:

7 == (3+4) ‘a’ == ‘\141’ 2 == 2.0

For objects: == implements object identity, therefore: new Integer(7) != new Integer(3+4)

If we really want object equality instead of object identidy: equals method

Page 13: Implications of Inheritance COMP206, Geoff Holmes and Bernhard Pfahringer.

Equality test: object equality Supplied by class Object, can be

overridden:class Circle extends Shape { …

public boolean equals(Object arg) {return ((arg instanceof Circle) && (radius == ((Circle) arg).radius));}}

Careful: must be symmetric and transitive Heuristic: use == for numbers and null,

equals in all other situations

Page 14: Implications of Inheritance COMP206, Geoff Holmes and Bernhard Pfahringer.

Equality test: bug example Suppose:

class Shape { …public boolean equals(Object arg) {

return ((arg instanceof Shape) && (x == ((Shape) arg).x) && (y == ((Shape) arg).y)) ;}}

And no equals defined in class Square, then:Square s = new Square(10,10,5);Circle c = new Circle(10,10,5);s.equals(c); // succeedsc.equals(s); // fails

Page 15: Implications of Inheritance COMP206, Geoff Holmes and Bernhard Pfahringer.

Better solution class Shape { …

public boolean equals(Object arg) {return ((arg.getClass() == Shape.class) && (x == ((Shape) arg).x) && (y == ((Shape) arg).y)) ;}}

class Circle extends Shape { …public boolean equals(Object arg) {

return ((arg.getClass() == Circle.class) && (x == ((Shape) arg).x) && (y == ((Shape) arg).y) && (radius == ((Circle) arg).radius));}}

correct, but no inheritance, code duplication

Page 16: Implications of Inheritance COMP206, Geoff Holmes and Bernhard Pfahringer.

Garbage collection (GC) Heap-based memory not automatically

recovered on method exit (unlike stack) Manual management error-prone (like

“free” operator in C++): Forget to free: memory leaks Free multiple times Access freed memory

Java compromise: have automatic garbage collection: some runtime cost, but not too bad)

Page 17: Implications of Inheritance COMP206, Geoff Holmes and Bernhard Pfahringer.

Immutable objects cannot be changed after “construction” how to:

do not allow modification by not providing “mutators” (methods that change state)

making data fields “private” (always good idea) (most likely) prevent against subclassing

useful for “value” types, like Integer, String, and so on; safe to use as keys for HashMaps (see code example for explanation)

hashCode “rule”: a.equals(b) == true => a.hashCode() == b.hashCode()

[only this direction, different objects can have the same hashCode]

Page 18: Implications of Inheritance COMP206, Geoff Holmes and Bernhard Pfahringer.

Object construction

no explicit constructor: system adds “default constructor”:

public A() { super(); } At least one constructor given explicitly: no

“default constructor” will be added first line in the constructor can explicitly pass

on to constructor of the super-class or same class (if not, system will add “super();”)

public A() { super(“info”); /* more code */ } public A() { this(0); /* more code */ }

Page 19: Implications of Inheritance COMP206, Geoff Holmes and Bernhard Pfahringer.

Construction order Data fields are allocated and initialized to

default values (0, null, …) *before any* code blocks or constructors;

Then the process is top-down (most general class first to most specific last), each time:

Data fields are initialized to their actual values (e.g. 1 in the code example), in order

Local code blocks are run, in order The respective constructor is run

Page 20: Implications of Inheritance COMP206, Geoff Holmes and Bernhard Pfahringer.

Bad Inheritance exampleimport java.util.*;

public class InstrumentedArrayList extends ArrayList { // The number of attempted element additions private int addCount = 0;

public InstrumentedArrayList() { }

public InstrumentedArrayList(Collection c) { super(c); }

public InstrumentedArrayList(int initialCapacity) { super(initialCapacity); }

Page 21: Implications of Inheritance COMP206, Geoff Holmes and Bernhard Pfahringer.

cont.public void add(int index, Object o) { addCount++; super.add(index,o); }

public boolean addAll(Collection c) { addCount += c.size(); return super.addAll(c);}

public int getAddCount() { return addCount; }

public static void main(String[] args) { InstrumentedArrayList s = new InstrumentedArrayList(); s.addAll(Arrays.asList(new String[] {”A",”B",”C"})); System.out.println(s.getAddCount()); }}

Page 22: Implications of Inheritance COMP206, Geoff Holmes and Bernhard Pfahringer.

Better: use Compositionimport java.util.*;

public class InstrumentedList implements List { private final List s; private int addCount = 0;

public InstrumentedList(List s) { this.s = s; }

public void add(int index, Object o) { addCount++; s.add(index, o); }

public boolean addAll(Collection c) { addCount += c.size(); return s.addAll(c); }

Page 23: Implications of Inheritance COMP206, Geoff Holmes and Bernhard Pfahringer.

Composition, cont.public int getAddCount() { return addCount; }

// plus all necessary forwarding methods public void clear() { s.clear(); } public boolean contains(Object o) { return s.contains(o); } public boolean isEmpty() { return s.isEmpty(); } … and so on …

Page 24: Implications of Inheritance COMP206, Geoff Holmes and Bernhard Pfahringer.

Utilities: Arrays class, Collections lots of useful utilities, have a look at the Javadoc, e.g.

Arrays.sort(…) Arrays.binarySearch(..) Arrays.toString(..) Arrays.fill(..) Arrays.hashCode(..) Arrays.equals(..) Arrays.asList(..) Arrays.deepEquals(..), deepToString(..) deepHashCode(..) Collections.shuffle(..)

Page 25: Implications of Inheritance COMP206, Geoff Holmes and Bernhard Pfahringer.

Utilities: System class again lots of useful utilities, have a look at the Javadoc,

e.g. System.arraycopy(..) System.nanoTime() System.identityHashCode(..) System.getenv(..) …