Vous êtes sur la page 1sur 9

1

14. Mechanisms for Software Reuse

5/5/18

John Roberts

2
Overview
• Inheritance vs. Composition,

Part 1

• Abstract classes vs. 



Interfaces

• Inheritance vs. Composition,



Part 2

• Advantages and
Disadvantages

• Combining Composition and


Inheritance

3
Inheritance vs. Composition (Aggregation) Part 1

• is-a vs. has-a

• Car is-a Vehicle (inheritance)

• Case has-a Engine (composition)

• Will the is-a relationship be constant throughout the


lifetime of the application?
4
Inheritance vs. Composition (Aggregation) Part 1

• Initially, Employee is-a Person

• But, Employee might be a role played by a Person at certain points


in time

• What if the Person becomes unemployed?

• What if the Person is both an Employee and a Supervisor?

• Normally, we use Composition to model these relationships



class Person {

Role workingRole;

// …

}

5
Overview
• Inheritance vs. Composition,

Part 1

• Abstract classes vs.


Interfaces

• Inheritance vs. Composition,



Part 2

• Advantages and
Disadvantages

• Combining Composition and


Inheritance

6
Abstract classes vs. Interfaces

• Abstract classes are used when you want to share the


structure or code among super- and sub-classes

• Interfaces are used when you want to share the


specification of behavior but no code
7 Note code applicable to all sub classes; we’ll need this same operation
Example

public abstract class AST {


// …
protected ArrayList<AST> kids;

public AST getKid( int i ) {


if ( (i <= 0) || (i > kidCount())) {
return null;
}

return kids.get(i - 1);


}
}

8 Note implementation details may change, but behavior is consistent


Example

public interface java.util.Enumeration {


public abstract boolean hasMoreElements();
public abstract Object nextElement();
}

9
Overview
• Inheritance vs. Composition,

Part 1

• Abstract classes vs. 



Interfaces

• Inheritance vs. Composition,



Part 2

• Advantages and
Disadvantages

• Combining Composition and


Inheritance
10
Inheritance vs. Composition (Aggregation) Part 2

• Consider two different possible implementations of a


Stack in Java
class Stack extends Vector { class Stack {
public Object push( Object item ) { private Vector theData;
addElement( item );
return item; public Stack() {
} theData = new Vector();
public Object peek() { }
return elementAt( size() - 1 );
} public boolean isEmpty() {
} return theData.isEmpty();
}
}

11
Inheritance vs. Composition (Aggregation) Part 2
class Stack extends Vector {
public Object push( Object item ) { • Stacks can use protected
addElement( item );
members of Vector
return item;
}
public Object peek() { • Stacks can be used wherever
return elementAt( size() - 1 );
Vectors are required as
}
} arguments

• Reuse Vector methods such as


size, isEmpty

• Reuse methods that might not


make sense for Stacks (we can
remove any item in a Vevtor)

12
Inheritance vs. Composition (Aggregation) Part 2
class Stack {
• We can change the private Vector theData;
implementation of Stack from
public Stack() {
Vectors to e.g. array, without theData = new Vector();
any impact on code that uses }
Stacks
public boolean isEmpty() {
return theData.isEmpty();
• Surface area is smaller (don’t }
need to understand Vectors in }
order to understand Stacks)

• Meaningless behavior isn’t


exposed (extending Vector
allows us to do things to Stacks
like insertElementAt()
13
Overview
• Inheritance vs. Composition,

Part 1

• Abstract classes vs. 



Interfaces

• Inheritance vs. Composition,



Part 2

• Advantages and
Disadvantages

• Combining Composition and


Inheritance

14
Inheritance Advantages

• Substitutability

• Shorter implementation times due to code reuse

• Field/method access - Can access public and protected


members of the super class

• Polymorphism is available

15
Inheritance Disadvantages

• Tight coupling of subclass with superclass

• Changes to superclass have rippling effect on all


subclasses

• Users of a class with inheritance must look at the class


and all superclasses to understand behavior - large
surface area

• Might use methods in superclass that are not really


appropriate
16
Composition Advantages

• Easier to understand operations that are available (i.e. not


exposing inherited behaviors like we saw with Stack
extends Vector’s insertElementAt() )

• Changes to private data have no effect on users of class

17
Composition Disadvantages

• Field/method access - Can only access public members


of the composed class

• No polymorphism

18
Overview
• Inheritance vs. Composition,

Part 1

• Abstract classes vs. 



Interfaces

• Inheritance vs. Composition,



Part 2

• Advantages and
Disadvantages

• Combining Composition and


Inheritance
19
Combining Composition and Inheritance

• Very powerful

• Can be used to greatly simplify the inheritance hierarchy

20
Example: Java Stream Wrappers

• InputStream

• ByteArrayInputStream

• FileInputStream

• PipedInputStream

• FilterInputStream

• BufferedInputStream

• DataInputStream

21
Example: Java Stream Wrappers

• Subclassing allows processing an InputStream regardless


of where the bytes come from

class FilterInputStream extends InputStream {


// source of bytes is from any InputStream

protected InputStream in;

FilterInputStream( InputStream in ) { 

this.in = in;
}

// etc.

} 

22
Example: Java Stream Wrappers

• FilterInputStreams can be used wherever we expect an


InputStream since it subclasses InputStream

• It gets the bytes from in and then performs filtering

• In this case, we are provided with orthogonal sources of


variation - the source of bytes, and added functionality (e.g.
filtering, buffering)

• We are avoiding an explosion of the inheritance


hierarchy

• What if we don’t use composition with inheritance?

23
Example: Java Stream Wrappers

• Hierarchy grows exponentially

• InputStream

• FilterInputStream

• BufferedInputStream

• BufferedDataInputStream

• // A lot more

• DataInputStream

• // etc.

24 Leveraging implementation of shared code, adding new behavior


Example: BufferedReader

• http://developer.classpath.org/doc/java/io/BufferedReader-source.html

• 63: Reader in;



composition adds buffering services to the Reader it is wrapping

• 64: char[] buffer;



the buffered characters read from in

• 117: // new constructor

• 102: // use new constructor (with


DEFAULT_BUFFER_SIZE)

• 429: // readLine method added


25 Composition
Dynamic Composition

• Combining composition and inheritance to change the


behavior of a program as it is running (dynamically)
class Frog {

private FrogBehavior behavior;

public Frog() {

behavior = new TadpoleBehavior();
}

public grow() {
// see if behavior should change
if (behavior.growUp()) {
behavior = new AdultFrogBehavior();
}

behavior.grow(); // behavior does actual work


behavior.swim();
}
}

26 Inheritance
Dynamic Composition

• Combining composition and inheritance to change the


behavior of a program as it is running (dynamically)
abstract class FrogBehavior {

public boolean growUp() { return false; }
public abstract void grow();

public abstract swim();
}

class TadpoleBehavior extends FrogBehavior {


private int age = 0;
public boolean growUp() {
return (++age > 24)? true : false;
}
public void grow() {...}

public void swim() {...}
}

class AdultFrogBehavior extends FrogBehavior {


public void grow() {...}

public void swim() {...}
}

Vous aimerez peut-être aussi