Presentation is loading. Please wait.

Presentation is loading. Please wait.

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

Similar presentations


Presentation on theme: "From Theory to Practice 1 OOP 2006. Overview Reminder – some OOD principles from previous lessons: –Class Inheritance vs. Object Composition –Program."— Presentation transcript:

1 From Theory to Practice 1 OOP 2006

2 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 / http://java.sun.com/docs/books/effective /

3 Inheritance vs. Composition Reminder 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

4 Example – Profiling a HashSet Recall some Map API functions: –boolean add(E o) –boolean addAll(Collection c) One implementing class is HashSet. Some constructors of this class are: –HashSet() –HashSet(Collection 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

5 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); }

6 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

7 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

8 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

9 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

10 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

11 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

12 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 5  Use common sense to weigh the tradeoffs

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

14 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 (L inkedList )

15 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?

16 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 –Enable safe and powerfull functionality enhancements As in the previous example of InstrumentedMap Interfaces vs. Abstract Classes

17 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

18 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 –Examples: AbstractCollection, AbstractSet, AbstractList, AbstractMap

19 Example - AbstractMapEntry Note that this class in not included in the Java Platform library public abstract class AbstractMapEntry implements Map.Entry { // 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() }

20 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

21 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

22 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 …


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

Similar presentations


Ads by Google