Inheritance Template Method Pattern Factory Method Pattern 2 Class Reuse Two forms of class reuse Class implementation inheritance extends in Java Different than implements which is interface inheritance ID: 934624
Download Presentation The PPT/PDF document "1 Computer Science 340 Software Design &..." is the property of its rightful owner. Permission is granted to download and print the materials on this web site for personal, non-commercial use only, and to display it on your personal computer provided you do not modify the materials and that you retain all copyright notices contained in the materials. By downloading content from our website, you accept the terms of this agreement.
Slide1
1
Computer Science 340Software Design & Testing
Inheritance
Template Method Pattern
Factory Method Pattern
Slide22
Class ReuseTwo forms of class reuse:Class implementation inheritance
“extends” in JavaDifferent than “implements”, which is “interface inheritance”Object composition
Slide33
Class Inheritance
This class is like that class except for these differences …
Specialize superclass behavior by overriding methods
Totally replace a superclass operation
Add pre/post processing before/after superclass operation
Extend superclass by adding new variables/operations
4
Class Inheritance
Inheritance establishes a subtyping relationship between subclass and superclass, thus enabling polymorphism
Polymorphism = Subtyping + Dynamic method binding
Subclass instances may be used anywhere superclass instances are expected
Liskov
Substitution Principle
Slide55
Object Composition
Client class creates an internal instance of existing class and invokes its functionality through regular method calls
Generally results in looser coupling than the inheritance relationship
With inheritance, changes to A are more likely to break B than with composition
No subtyping relationship is established between the two classes, thus preventing polymorphism
Extra levels of indirection in method calls can reduce efficiency, but this usually isn
’
t a problem
Slide66
Choosing Between Composition Inheritance
What type of relationship is being modeled?B “has-a” A => compositionB “uses” A => compositionB “is-a” A => inheritance
Specialization
Slide77
Choosing Between
Composition and Inheritance
“
Favor object composition over class inheritance.
”
[Design Patterns, pg. 20]
Composition is:
More flexible than inheritance
Leads to lower coupling than inheritance
Allows control over which delegate features are exposed, and what the API looks like
Often more complex than inheritance
Slide88
Choosing Between
Composition and Inheritance
Inheritance:
Supports polymorphism, while composition does not
Is easier if you want to expose many of the superclass
’
features
Although
Intellij
and Eclipse both have a handy
“
Generate Delegate Methods
”
option for exposing delegate features if you
’
re using composition
Slide99
Dynamic InheritanceDynamic inheritance is when you have objects that change class over time
Dynamic inheritance can be implemented using a combination of composition and interface inheritance
Slide1010
Dynamic Inheritance
Example: Vocations
This inheritance-based design is inflexible because once a person has been created, their vocation cannot change
Slide1111
Dynamic InheritanceExample: Vocations
This design uses a combination of composition (with delegation) and interface inheritance to allow a person’s vocation to change over their lifetime
Slide1212
Dynamic Inheritance
Another example of dynamic inheritance
Slide1313
Multiple Inheritance
Multiple inheritance is when an object is a member of multiple classes at once
Slide1414
Multiple Inheritance
What if you need multiple inheritance, but your programming language does not support it (like Java)?
This design uses a combination of composition and interface inheritance to allow a
PhdStudent
to be both an Instructor and a Student
PhdStudent
delegates method calls to Instructor and Student
Slide1515
Multiple Inheritance
Hybrid approach
Use implementation inheritance for one super-class, and interface inheritance + composition for the other super-classes
Which one should I use for implementation inheritance?
The one that most closely matches the ”is-a” rule.
16
Inheritance-Based ReuseInheritance is a more tightly coupled relationship than composition
Inheritance is sometimes called “white box reuse”, and composition is called “black box reuse”Unwise programmers, when they realize they need to subclass an existing class, make all the “private” features “protected”, make all the methods “virtual”, and say, “There, now it’s a base class!”.
This approach results in extremely high coupling between a base class and its subclasses, and results in a fragile base class (i.e., a base class that is difficult to change without breaking its subclasses)
To minimize coupling, the “subclass interface” between a base class and its subclasses should be carefully designed
Information hiding is still a good practice, even between super- and sub-classes
Slide1717
Designing the Subclass InterfaceSubclasses need to:
Access base class features in ways not available through the public interfaceSpecialize base class behavior
Public Interface
Subclass
Interface
Base Class
Sub Class
Client
Client
Slide1818
Designing the Subclass InterfaceBase classes should typically keep their variables private, and provide protected methods that allow subclasses to access or modify their state only in necessary, controlled ways
Make a variable protected only if there is a good reason to do so
Public Interface
Subclass
Interface
Base Class
Sub Class
Client
Client
Slide1919
Designing the Subclass InterfaceKeep methods private when subclasses don’t need to access or override them
Base classes should define polymorphic methods for aspects of their behavior that subclasses can specializeVirtual methods in C++
All non-final methods in JavaMake a method polymorphic only if you expect subclasses to specialize itSpecifically prevent specialization of methods that subclasses should not override
Non-virtual methods in C++
“final” methods in Java
Public
Interface
Subclass
Interface
Base Class
Sub Class
Client
Client
Slide2020
Designing the Subclass InterfaceKeeping the subclass interface as simple as possible has two positive outcomes:
There is more freedom to change the internal implementation of the base class without breaking subclasses (i.e., base classes are less fragile)
It is easier for subclass authors to understand how to specialize the base class (i.e., they have less freedom, but more guidance)
Public
Interface
Subclass
Interface
Base Class
Sub Class
Client
Client
Slide2121
Patterns for Designing the Subclass InterfaceTemplate Method patternFactory Method pattern
Slide2222
Template Method PatternCode that is duplicated in multiple places should be centralized in one place (i.e., avoid duplication)
Composition: Put common code in a method on a class to which multiple clients will delegateInheritance
: Put the common code in a method on a super-class, and make the clients sub-classes (i.e., clients inherit common code)What if an algorithm is duplicated in several places, but the copies are SIMILAR rather than IDENTICAL?Use the Template Method pattern
Put the common algorithm in a super-class
Clients inherit common code from super-class
Some steps of the algorithm are delegated to subclasses through polymorphic method calls
Subclasses customize the algorithm by implementing the delegated steps
Slide23Template Method Pattern
23
Slide2424
/**
* An abstract class that is common to several games in
* which players play against the others, but only one is
* playing at a given time.
*/
abstract
class
Game {
protected
int
playersCount
;
/* A template method : */
public
final
void
playOneGame
(
int
playersCount
) {
this
.playersCount
=
playersCount
;
initializeGame
();
int
j = 0;
while
(!
endOfGame
()) {
makePlay
(j);
j = (j + 1) %
playersCount
;
}
printWinner
();
}
abstract
void
initializeGame
();
abstract
void
makePlay
(
int
player);
abstract
boolean
endOfGame
();
abstract
void
printWinner
();
}
//Now we can extend this class in order
//to implement actual games:
class
Monopoly
extends
Game {
/* Specific declarations for the Monopoly game. */
/* Implementation of abstract methods */
void
initializeGame
() {
// Initialize players
// Initialize money
}
void
makePlay
(
int
player) {
// Process one turn of player
}
boolean
endOfGame
() {
// Return true if game is over
// according to Monopoly rules
}
void
printWinner
() {
// Display who won
}
/* Specific methods for the Monopoly game. */
// ...
}
Refactoring with the Template Method Pattern
Make the similar code as similar as possible in the classes that duplicate it
Similar code diverges unnecessarily over timeCreate a common base class for all classes with similar codePut one copy of the similar code/method(s) in the parent (this becomes the template method)
Identify and extract what needs to vary by subclassCreate abstract methods for the code that needs to varyReplace the code that needs to vary with calls to the abstract methods in the template method
Override the abstract methods in the subclasses with their version of the varying code (pulled out of their copy of the template method override(s))
Delete the template method override(s) in the subclasses
25
Slide2626
Factory Method PatternFactory Method pattern
A super-class contains useful functionality that can be inherited by sub-classesThe super-class needs to instantiate an object to do its work, but it is a general class and has many potential uses. Therefore, it doesn’t know the concrete class of the object it needs so it can’t instantiate it
Instantiation of the object is delegated to sub-classes, which do know which concrete class to instantiate
Slide27Factory Method Pattern
27
Slide2828
interface Vehicle{
public void drive();
}
class Car implements Vehicle{
@Override
public void drive(){
System.out.println
("Driving a car...");
}
}
class Bus implements Vehicle{
@Override
public void drive(){
System.out.println
("Driving a Bus...");
}
}
abstract class
VehicleDriver
{
public void
driveVehicle
(){
Vehicle v =
makeVehicle
();
v.drive
();
}
public abstract Vehicle
makeVehicle
();
}
class
CarDriver
extends
VehicleDriver
{
@Override
public Vehicle
makeVehicle
(){
return new Car();
}
}
class
BusDriver
extends
VehicleDriver
{
@Override
public Vehicle
makeVehicle
(){
return new Bus();
}
}
Slide2929
public class
FactoryMethodPattern
{
public static void main(String[]
args
) {
handleVehicle
(new
CarDriver
());
handleVehicle
(new
BusDriver
());
}
static void
handleVehicle
(
VehicleDriver
vDriver
){
System.out.println
("Handling a new vehicle.");
vDriver.driveVehicle
();
}
}
Handling a new vehicle.
Driving a car...
Handling a new vehicle.
Driving a Bus...