From Theory to Practice 1
OOP 2006
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/
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
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
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);
}
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
• 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
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
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
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
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
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
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.
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)
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?
• 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
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
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
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()
}
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
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
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 …
Top Related