SDSU CS 596 OODP
Polymorphism

[To Lecture Notes Index]
San Diego State University -- This page last updated November 16, 1995
----------

Contents of Polymorphism Lecture

  1. Polymorphism
    1. Hot Shot Polymorphism and C++
    2. How to Increase the use of Pure Polymorphism
      1. Rules for Finding Standard Protocols

Polymorphism


Polymorphic many forms


Polymorphic Object
Programming entity that is permitted to hold values of differing types


Levels of Polymorphism
Pure (Parametric) Polymorphism
An entity has more than one form


Ad Hoc Polymorphism (Overloading)
Different entities have the same name



Algorithm Analogy
The sort algorithm works on may different types
Verses Pascal implementation of a sort algorithm

Polymorphic Objects


A programming object (variable) can hold values of different types.

Source of most of polymorphism in OOPL


Dynamically Bound languages
Smalltalk, Objective-C, CLOS
All objects are potentially polymorphic
x := 5;
x := 5.5;
x := 'This is a string';


C++
Requires use of pointers
class A { ... }
class B : public A { ... }
A* polyVariable;
polyVariable = new A;
polyVariable = new B;

Simple Polymorphism and C++
#include <iostream.h>

class  Top {
public:
	void virtual DoIt();
};

void Top::DoIt() {
cout << "Top" << endl;
}


class Bottom : public Top {
	void virtual DoIt();
};

void Bottom::DoIt() {
	cout << "Bottom" << endl;
}


main() {
	Top*  WhyMe = new Top;

	WhyMe->DoIt();			// prints "Top"

	WhyMe = new Bottom;

	WhyMe->DoIt();			// prints "Bottom"

}

Hot Shot Polymorphism and C++

#include <iostream.h>

class  Top {
public:
	void DoIt();
	void virtual FunPart() {cout << "Part1 in Top" << endl;}
};

void Top::DoIt() {
	cout << "Top" << endl;
	FunPart();
}


class Bottom : public Top {
	void virtual FunPart();
};

void Bottom::FunPart() {
	cout << "This is it" << endl;
}


main() {
	Top*  WhyMe = new Top;

	WhyMe->DoIt();			// prints "Top \n Part1 in Top"

	WhyMe = new Bottom;

	WhyMe->DoIt();			// prints "Top \n This is it"
}

Polymorphism

main()
{
	Account*  customer;

	customer = createNewAccount();

	customer->Transaction(amount);
}

Polymorphism
class Account {
	public:	
		void virtual Transaction(float amount) 
									{ balance += amount;}
		Account(char* customerName, float InitialDeposit = 0);
	protected:
		char* name;
		float balance;
}

class JuniorAccount : public Account {
	public:	void Transaction(float amount) {//  put code here}
}

class SavingsAccount : public Account {
	public:	void Transaction(float amount) {//  put code here}
}

Account* createNewAccount()
{
	// code to query customer and determine what type of
	// account to create
};


main()
{
	Account*  customer;

	customer = createNewAccount();

	customer->Transaction(amount);
}

Hot Shot Polymorphism
class Account {
	public:	
		void 	Transaction(float amount);
		void virtual TransactionSubpartA();
		void virtual TransactionSubpartB();
		void virtual TransactionSubpartC();
}

void Account::Transaction(float amount)  {
	TransactionSubpartA();		TransactionSubpartB();	
	TransactionSubpartC();		// EvenMoreCode;
}

class JuniorAccount : public Account {
	public:		void virtual TransactionSubpartA(); }

class SavingsAccount : public Account {
	public:		void virtual TransactionSubpartC(); }

Account*  customer;
customer = createNewAccount();
customer->Transaction(amount);

Polymorphism
The Good

Making modifications to program require:
Adding new subclasses
Changing code that creates objects


Account* customer;
customer = createNewAccount();
customer->Transaction(amount);
Polymorphism and C++
The Bad
The root base class needs to "know" about operations in all subclasses


Account* customer;
customer = createNewAccount();
customer->Foo(); // compile error
Modular Design Rules
Avoid Case Statements
if X is a Account then
	X.AccountUpDate()
else if X is a JuniorAccount then
	X.JuniorAccountUpDate()

Case X
Account: X.AccountUpDate()
	JuniorAccount:  X.JuniorAccountUpDate()
end case
Use Polymorphism
X->Update()

where Account class and JuniorAccount class have an Update operation

Supports:
Composability                                 Continuity                                    


Modular Design Rules
Small Is Beautiful

Operation Size

Upper bound for average size of an operation
Language
Lines of Code
Smalltalk
8
C++
24




Class Size

Average number of operations per class should be less than 20
Large classes should be viewed with suspicion and held guilty of poor design until proven innocent
Supports:
       Decomposability Composability          Understandability                             


Modular Design Rules
Small Is Beautiful - Continued


Keep the number of parameters per operations small
Operations with few parameters are more likely to be usable in different classes
Reduce the number of parameters by:
Breaking an operation into several smaller operations
Creating a new class that represents a group of arguments


Supports:
       Decomposability Composability          Understandability                             


How to Increase the use of Pure Polymorphism



* Polymorphic Objects

* Overloading of small chunks of code




Protocol
Name and arguments of public operations of an object



Plug Compatible Objects
Objects with the same protocol
Standard Protocol

Using the same name for similar processes

Rules for Finding Standard Protocols

(To Encourage Pure Polymorphism)


* Use small operations
Smalltalk methods average about 3 - 5 lines of code





Rules for Finding Standard Protocols
(To Encourage Pure Polymorphism)


* Reduce the number of arguments
Methods with small number of arguments are more likely to be usable in different classes
Reduce number of arguments by:
* Breaking a message into several smaller messages
* Creating a new class that represents a group of arguments


Rules for Finding Standard Protocols
(To Encourage Pure Polymorphism)


* Eliminate case analysis
*Checking class of an object
if (anObject class = integer) then
anObject.Foo;

else
anObject.Fee;
Implement Foo in all relevant classes to perform the equivalent operation
anObject.Foo

* Case analysis of values of variables
Can be more difficult, but no less important
Rules for Finding Standard Protocols
(To Encourage Pure Polymorphism)


* Recursion introduction
If an operation X is implemented by performing a similar operation on the component of the receiver, then that operation should also be named X.
void OrderedLinkedList::add(int value)
{
cell *newCell;

newCell = new cell;
newCell->value = value;
listHead->add(*newCell);
};

----------