Professional Documents
Culture Documents
1. Inheritance vs Composition
When the inheritance is-a role is not “constant” throughout the application: An employee is a
person but could be just a role which might not be valid when a person becomes unemployed.
And the role could be both employee and supervisor: Use composition.
Class Person {
Role workingRole;
// …
}
Abstract classes: Sharing structure code among inherited classes (super- and sub-)
Interfaces: Sharing specific behavior without code.
Implementing stack through inheritance from Vector can use protected members of Vector as
well as its methods such as size, isEmpty, including those that might not behave as Stacks
(Vector can remove any item while Stack can only Last-In-First-Out) . Stacks can be
implemented the same as Vectors wherever required as arguments.
Class Stack {
Private Vector theData;
Public Stack() {
theData = new Vector();
}
Inheritance:
V Substitutability
V Code reusability with shorter implementation times
V Member and method accessibility (public and protected members of the super class)
V Polymorphism
X Tight coupling (between subclass and superclass)
X Changes to superclass affects all subclasses with rippling effect
X Large surface area (need to understand all superclasses to understand a class’s behavior with
inheritance)
X Possible inappropriate behavior of methods from superclass
Composition:
V Easy to understand available operations (while hiding inherited behaviors not applicable)
V Changes in private member has no effect on class usage.
X No member and method accessibility on composed class, only public members.
X No polymorphism
InputStream
ByteArrayInputStream
FileInputStream
PipedInputStream
FilterInputStream
BufferedInputStream
BufferedInputStream
// more
DataInputStream
// more
FilterInputStream( InputStream in ) {
This.in = in;
}
// etc.
}
Example: BufferedReader
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();
}
}