From Theory to Practice 1 OOP 2006. Overview Reminder – some OOD principles from previous lessons:...

22
From Theory to Practice 1 OOP 2006
  • date post

    22-Dec-2015
  • Category

    Documents

  • view

    219
  • download

    1

Transcript of From Theory to Practice 1 OOP 2006. Overview Reminder – some OOD principles from previous lessons:...

Page 1: From Theory to Practice 1 OOP 2006. Overview Reminder – some OOD principles from previous lessons: –Class Inheritance vs. Object Composition –Program.

From Theory to Practice 1

OOP 2006

Page 2: From Theory to Practice 1 OOP 2006. Overview Reminder – some OOD principles from previous lessons: –Class Inheritance vs. Object Composition –Program.

Overview

• Reminder – some OOD principles from previous lessons:– Class Inheritance vs. Object Composition– Program to an interface and not an implementation– Modularity

• The impact of these and other principles is greatly illustrated in the book Effective Java™

by Joshua Bloch– The book contains many rules of thumb

for writing a code that is clear, correct,robust and reuseable

– Most code samples are taken from http://java.sun.com/docs/books/effective/

Page 3: From Theory to Practice 1 OOP 2006. Overview Reminder – some OOD principles from previous lessons: –Class Inheritance vs. Object Composition –Program.

Inheritance vs. CompositionReminder

• The two most common techniques for reusing functionality are inheritance and composition

• Class Inheritance– Define implementation of one class in terms of another– The internals of the parent are visible to subclass

• Object Composition– New functionality is obtained by assembling objects– No internal details of objects are visible

• There are pros and cons for each alternative• But, the common rule of thumb is:

Favor Composition over Inheritance

Page 4: From Theory to Practice 1 OOP 2006. Overview Reminder – some OOD principles from previous lessons: –Class Inheritance vs. Object Composition –Program.

Example – Profiling a HashSet

• Recall some Map<E> API functions:– boolean add(E o)– boolean addAll(Collection<? extends E> c)

• One implementing class is HashSet<E>.Some constructors of this class are:– HashSet()– HashSet(Collection<? extends E> c)– HashSet(int initialCapacity, float loadFactor)

• We would like to add a profiling function:– int getAddCount()This function returns the number of attempted element

insertions

Page 5: From Theory to Practice 1 OOP 2006. Overview Reminder – some OOD principles from previous lessons: –Class Inheritance vs. Object Composition –Program.

Using Inheritance

import java.util.*;

public class InstrumentedHashSet extends HashSet{

// The number of attempted element insertions

private int addCount = 0;

public InstrumentedHashSet() {}

public InstrumentedHashSet(Collection c) {

super(c);

}

public InstrumentedHashSet

(int initCap, float loadFactor) {

super(initCap, loadFactor);

}

Page 6: From Theory to Practice 1 OOP 2006. Overview Reminder – some OOD principles from previous lessons: –Class Inheritance vs. Object Composition –Program.

public boolean add(Object o) {

addCount++;

return super.add(o);

}

public boolean addAll(Collection c) {

addCount += c.size();

return super.addAll(c);

}

public int getAddCount() {

return addCount;

}

Using Inheritance – Handling Counts

Page 7: From Theory to Practice 1 OOP 2006. Overview Reminder – some OOD principles from previous lessons: –Class Inheritance vs. Object Composition –Program.

• What is the result of the following code?

• Unfortunately the answer is 6• The reason: addAll uses add

public static void main(String[] args) {

InstrumentedHashSet s = new InstrumentedHashSet();

s.addAll(Arrays.asList(new String[] {"Snap","Crackle","Pop"}));

System.out.println(s.getAddCount());

}

Using Inheritance – Results

Page 8: From Theory to Practice 1 OOP 2006. Overview Reminder – some OOD principles from previous lessons: –Class Inheritance vs. Object Composition –Program.

Possible Solutions

• Do not override addAll:– Problem: depends on implementation details

• Write addAll using iteration and add.Cons:– Complete re-implementation of the method– Sometimes requires access to private members

• Another problem with previous solutions:– What if a different add function is add to HashSet?

• Another alternative: Composition

Page 9: From Theory to Practice 1 OOP 2006. Overview Reminder – some OOD principles from previous lessons: –Class Inheritance vs. Object Composition –Program.

import java.util.*;

public class InstrumentedSet implements Set {

private final Set s;

private int addCount = 0;

public InstrumentedSet(Set s)

{ this.s = s; }

public boolean add(Object o) {

addCount++; return s.add(o);

}

public boolean addAll(Collection c) {

addCount += c.size(); return s.addAll(c);

}

public int getAddCount() {

return addCount; }

Using Composition

Decorator

Pattern

Page 10: From Theory to Practice 1 OOP 2006. Overview Reminder – some OOD principles from previous lessons: –Class Inheritance vs. Object Composition –Program.

public void clear()

{ s.clear(); }

public boolean contains(Object o)

{ return s.contains(o); }

public boolean isEmpty()

{ return s.isEmpty(); }

public int size()

{ return s.size(); }

public Iterator iterator()

{ return s.iterator(); }

public boolean remove(Object o)

{ return s.remove(o); }

public boolean containsAll(Collection c)

{ return s.containsAll(c); }

Forwarding Methods

A forwarding method is a method in the wrapper class which invokes the corresponding method in the contained class and returns the result

Page 11: From Theory to Practice 1 OOP 2006. Overview Reminder – some OOD principles from previous lessons: –Class Inheritance vs. Object Composition –Program.

public boolean removeAll(Collection c)

{ return s.removeAll(c); }

public boolean retainAll(Collection c)

{ return s.retainAll(c); }

public Object[] toArray()

{ return s.toArray(); }

public Object[] toArray(Object[] a)

{ return s.toArray(a); }

public boolean equals(Object o)

{ return s.equals(o); }

public int hashCode() { return s.hashCode(); }

public String toString()

{ return s.toString(); }

}

Forwarding Methods - cont

Page 12: From Theory to Practice 1 OOP 2006. Overview Reminder – some OOD principles from previous lessons: –Class Inheritance vs. Object Composition –Program.

The Pros and Cons of Composition

• Pros for composition– The underlying Set is completely encapsulated while

inheritance breaks encapsulation– Robust, not implementation dependent – Flexible, the profiling functionality works with any kind of set

• Pros for inheritance– Only methods concerned with new functionality need to be

overridden– Natural choice for some ‘is-a’ relations (e.g. Strategy, and

Composite patterns)

• Additional pros and cons in the slides of Lecture 5Use common sense to weigh the tradeoffs

Page 13: From Theory to Practice 1 OOP 2006. Overview Reminder – some OOD principles from previous lessons: –Class Inheritance vs. Object Composition –Program.

Program to an interface and not an implementation

• Reminder from lecture 5:Variables should not be instances of a particular concrete class. Instead commit only to an interface defined by an abstract class.

• Therefore, if an appropriate interface types exists, parameters, return values, variables and fields should all be declared using interface types.

• The only reference to an object class is when creating it.

Page 14: From Theory to Practice 1 OOP 2006. Overview Reminder – some OOD principles from previous lessons: –Class Inheritance vs. Object Composition –Program.

Example

• Good, uses interface as type: List subscribers = new Vector();

• Bad, use class as type Vector subscribers = new Vector();

• Using interfaces increase flexibility, such as changing implementation: List subscribers = new ArrayList();

• However, this should be done carefully, considering behavioral differences

• Exceptions to the principle: – Classes without interfaces (such as String) – Classes with extra functionality (LinkedList)

Page 15: From Theory to Practice 1 OOP 2006. Overview Reminder – some OOD principles from previous lessons: –Class Inheritance vs. Object Composition –Program.

Building a Good Interface

• We would like to supply a good interface to the client

• In Java types the permit multiple implementations can be defined as interfaces or as abstract class– Abstract classes allow implementation of some

methods while interfaces do not allow this– A class can implement multiple interfaces while it can

inherit only from a single class

• Should we use Interfaces or Abstract Classes?

Page 16: From Theory to Practice 1 OOP 2006. Overview Reminder – some OOD principles from previous lessons: –Class Inheritance vs. Object Composition –Program.

• Advantages of interfaces– Existing class can be easily retrofitted to implement

a new interface • Example: Comparable

– Allows construction of non-hierarchical type frameworks

• Example: Integer is both Serializable, Comparable<Integer>

– Enable safe and powerfull functionality enhancements

• As in the previous example of InstrumentedMap

Interfaces vs. Abstract Classes

Page 17: From Theory to Practice 1 OOP 2006. Overview Reminder – some OOD principles from previous lessons: –Class Inheritance vs. Object Composition –Program.

Interfaces vs. Abstract Classes

• Advantages of abstract classes– Provides default implementation– It is far easier to evolve an abstract class than it is to

evolve an interface:What happens to the implementing classes if we add a new function to the interface?

• Some advantages can be combined

Page 18: From Theory to Practice 1 OOP 2006. Overview Reminder – some OOD principles from previous lessons: –Class Inheritance vs. Object Composition –Program.

Skeletal Implementations

• Skeletal implementations Combine the advantages of interfaces and the ability to provide default implementation in an abstract class

• These are abstract classes implementing some of the methods defined in the interface

• Naming convention Abstract<Interface>– Examples: AbstractCollection, AbstractSet, AbstractList, AbstractMap

Page 19: From Theory to Practice 1 OOP 2006. Overview Reminder – some OOD principles from previous lessons: –Class Inheritance vs. Object Composition –Program.

Example - AbstractMapEntry

Note that this class in not included in the Java Platform library

public abstract class AbstractMapEntry<K,V>

implements Map.Entry<K,V> {

// Primitives: must be implemented in the

// derived class

public abstract K getKey();

public abstract V getValue();

// Entries in modifiable maps must overide

// this method

public V setValue(V newValue) {

throw new UnsupportedOperationException()

}

Page 20: From Theory to Practice 1 OOP 2006. Overview Reminder – some OOD principles from previous lessons: –Class Inheritance vs. Object Composition –Program.

AbstractMapEntry - cont

// Implements the general contract of

// Map.Entry.hashCode

public int hashCode() {

return

(getKey()==null ? 0 : getKey().hashCode()) ^

(getValue()==null

? 0 : getValue.hashCode());

.

.

.

}

Additional implementations here

Page 21: From Theory to Practice 1 OOP 2006. Overview Reminder – some OOD principles from previous lessons: –Class Inheritance vs. Object Composition –Program.

Rules of Thumb for Interfaces

• Prefer interfaces to abstract classes• Public interfaces should be designed and

tested carefully– It is almost impossible to change an interface once

it is released

• If you export a non trivial interface, consider providing a skeletal implementation

• Use abstract classes only if ease of evolution is more important than flexibility and power

Page 22: From Theory to Practice 1 OOP 2006. Overview Reminder – some OOD principles from previous lessons: –Class Inheritance vs. Object Composition –Program.

From Requirements to Practicalities(Via Principles)

General requirements of a good software system

Correct ,Clear, Reusable, Robust, Efficient, More?

Principles• Favor composition over inheritance• Write to an interface• More…

Practicalities• Design patterns (e.g. Decorator for composition)• Using the Interface mechanism of Java, skeletal

implementation• Many more …