830 likes | 1.09k Views
Polymorphism. Lesson #7. Note: CIS 601 notes were originally developed by H. Zhu for NJIT DL Program. The notes were subsequently revised by M. Deek. Content. Definition and Basic Terminology Polymorphism and Dynamic Binding. Polymorphism.
E N D
Polymorphism Lesson #7 Note: CIS 601 notes were originally developed by H. Zhu for NJIT DL Program. The notes were subsequently revised by M. Deek
Content • Definition and Basic Terminology • Polymorphism and Dynamic Binding
Polymorphism • Polymorphism (poly = many and morph = states or forms, etc.) • Polymorphism is a concept where a single name may denote objects of different classes that are related by some common base class [Booch]. • In polymorphic languages some values and variables may have more than one type. • A function is polymorphic if it may be applied to arguments of different types.
Polymorphism and Overloading • Realized by using a set of monomorphic functions. Different code is used for different types. • Overloading means that the same operation is implemented through different methods with the same function name. For different types, different implementations (methods) of the same operation are executed.
Polymorphism and Overloading • Coercion is explicitly converting types (such as integer to real). An example of coercion is casting in C or C++.
Static and Dynamic Binding • When a reference to a member function is resolved at compile time, then static binding is used. • When a reference to a member function can only be resolved at run-time, then this is called dynamic binding.
Polymorphism and Dynamic Binding • To implement polymorphism, the programming language must support dynamic binding. • Polymorphism----- a concept • Dynamic binding -----implementation
Polymorphism and Dynamic Binding • Classical paradigm • function open_disk_file() • function open_tape_file() • function open_diskette_file() • Object-Oriented paradigm • Function My_File.open_file()
Polymorphism and Dynamic Binding • All that is needed is myFile.open() • Correct method invoked at run-time (dynamically). • Method open can be applied to objects of different classes. • Polymorphism
Polymorphism in C++ • Virtual functions and polymorphism • Abstract and Concrete classes
Polymorphism in C++ • The ability to manipulate instances of derived class through a set of operations defined in their base class. • Each derived class can implement the operations defined in the base class differently, while retaining a common class interface provided by the base class.
Polymorphism in C++ • Virtual Function • A non-static member function prefaced by the virtual specifier. • It tells the compiler to generate code that selects the appropriate version of this function at run-time.
Example #include <iostream.h> class Employee { public: void Display(); // non-virtual virtual void CalcPaycheck(); // virtual }; class SalariedEmployee :public Employee { public: void Display(); virtual void CalcPaycheck(); }; void Employee::CalcPaycheck() {cout << "Employee"<<"\n";}
Example void SalariedEmployee::CalcPaycheck() {cout << "SalariedEmployee"<<"\n";} void Employee::Display() { CalcPaycheck(); } void SalariedEmployee::Display() { CalcPaycheck();} int main() { Employee * ep = new SalariedEmployee; //... ep->Display(); return 0; }//ex7salemp.cpp, Result: SalariedEmployee
Common Interface #include <iostream.h> class Employee { public: long GetDepartment() const{return deptNum;}; long GetId() const{return id;}; void SetDepartment( long deptId ){}; void SetId(){}; virtual void CalcPaycheck() =0; virtual void Input(){}; private: long id; long deptNum; };
Common Interface • class SalariedEmployee :public Employee {public: • Void CalcPaycheck(){cout<<"SalariedEmployee"<<endl;}; • class HourlyEmployee :public Employee {public: • void CalcPaycheck(){cout<<"HourlyEmployee"<<endl;}; • void ProcessAnyEmployee( Employee & er ) • { long anId = er.GetId(); // non-virtual • er.CalcPaycheck(); // virtual • } • void main() • {SalariedEmployee S; • HourlyEmployee H; • ProcessAnyEmployee( S ); • ProcessAnyEmployee( H ); • }
Virtual Destructors • Calling the wrong destructor could be disastrous, particularly if it contains a delete statement. • Destructors are not inherited. One must be defined for each derived class. • Constructors are not inherited.
Virtual Destructors #include <iostream.h> class Item { public: Item(){id = 0;}; virtual ~Item(){ cout <<"Item deleted"<<endl;}; private: int id; };//ex7virdes.cpp
Virtual Destructors class BookItem: public Item { public: BookItem(){title = new char [50];}; virtual ~BookItem(){delete title; cout <<"BookItem deleted"<<endl;}; private: char * title; }; void main() { Item * p; p = new BookItem; delete p; }
Stop Ignore Retry
Abstract Classes • An abstract class is a class that can only be a base class for other classes. • Abstract classes represent concepts for which objects cannot exist. • A class that has no instances is an abstract class. • Concrete classes are used to instantiate objects.
An Abstract Class • In C++, a class that has one or more virtual functions is an abstract class. • An abstract class either contains or inherits at least one pure virtual function. • A pure virtual function is a virtual function that contains a pure-specifier, designated by the “=0”.
Shape Circle Polygon Example:
The Class Shape #include <iostream.h> class Point { }; class Shape { public: virtual ~Shape(){}; virtual void Draw() const = 0; virtual void MoveTo( int x2, int y2 ) = 0; virtual void Rotate( int degrees ) = 0; };
Shape class Circle :public Shape { public: Circle(){}; Circle( const Point & aCenter, float aRadius ){}; virtual ~Circle(){}; virtual void Draw() const{cout<<"Drawing!"<<endl;}; virtual void MoveTo( int x2, int y2) {cout<<"MoveTo"<<endl;}; virtual void Rotate( int degrees) {cout<<"Rotate!"<<endl;}; private: Point center; float radius; };
Shape class Polygon :public Shape { public: Polygon(); Polygon( Point & cent, Point * verts ); virtual ~Polygon(); private: Point center; Point * vertices; // array of Points };
Shape int main() { Circle C; C.Draw(); Point center; Point vertices[10]; //Cannot create instance of abstract class Polygon: // Polygon P( center, vertices ); return 0; }
An Abstract Derived Class • If a pure virtual function is not defined in a derived class, the derived class is also considered an abstract class. • When a derived class does not provide an implementation of a virtual function the base class implementation is used. • It is possible to declare pointer variables to abstract classes.
Example:Package Shipping • The input file includes record in the following format: • Tracking number, organization Zip code, destination Zip code,shipping date, cost, and weight . • For example: • 100101 31313 33130 960402 15.00 8.0
Package Shipping • The output file should be in the following format: 0: [100101,31313,33130,960402,15.00,8.00] 1: [102001,20000,96535,960403,7.50,4.50] 2: [100311,10101,12110,960405,5.00,3.00] 3: [101400,10000,70515,960410,5.30,3.20] 4: [110510,22222,33133,960412,15.00,10.50] Total weight of 5 packages = 29.2
Package Shipping • The table should be sorted in ascending order Packages sorted by tracking number...... 0: [100101,31313,33130,960402,15.00,8.00] 1: [100311,10101,12110,960405,5.00,3.00] 2: [101400,10000,70515,960410,5.30,3.20] 3: [102001,20000,96535,960403,7.50,4.50] 4: [110510,22222,33133,960412,15.00,10.50]
Package Shipping • The user enters a tracking number, then the program searches and displays the index and the detail of the package: Searching for package 101400 Found at position 2 ........................... Tracking number: 101400 Origination zip code: 10000 Destination zip code: 70515 Date sent: 960410 Shipment cost: 5.30 Package weight 3.20
The Design Item Table Package TableAsArray
Item.h #include <iostream.h> class Item { public: virtual ~Item() { } virtual int Compare( const Item & I2 ) const = 0; friend ostream & operator <<( ostream & os, const Item & I ); friend istream & operator >>( istream & inp, Item & I ); private: virtual void printOn( ostream & os ) const = 0; virtual void readFrom( istream & inp ) = 0; };
Package.h • #include <iostream.h> • #include "item.h" • class Package :public Item { • public: • Package(); • Package( long trackNumP, long originP, • long destinP, long dateP, • float costP, float weightP ); • long GetDestination() const; • long GetTrackingNumber() const;
Package.h • float GetWeight() const; • void PrintLong( ostream & os ) const; • int Compare( const Item & I2 ) const; • void SetTrackNum( long trackNumP ); • void SetOrigin( long originP ); • void SetDestination( long destinP ); • void SetDate( long dateP ); • void SetCost( float costP ); • void SetWeight( float weightP ); • void Init();
Package.h • private: • long trackNum; // tracking number • long origin; // originating zip code • long destin; // destination zip code • long date; // date sent (yymmdd) • float cost; // shipping cost • float weight; // weight in kilograms • virtual void printOn( ostream & os ) const; • virtual void readFrom( istream & is ); • };
Table.h • #include "item.h" • #include "limits.h" • class Table { • public: • virtual ~Table() { } • virtual void AddItem( Item * I ) = 0; • virtual void Clear() = 0; • virtual unsigned GetCount() const = 0; • virtual Item * GetItemPtr( unsigned i ) const = 0; • virtual unsigned IndexOf( const Item * P ) const = 0; • virtual void Sort() = 0;// Ascending order • };
Tablearr.h • #include <iostream.h> • #include <iomanip.h> • #include <assert.h> • #include "table.h" • class TableAsArray : public Table { • public: • TableAsArray( unsigned tableSize ); • virtual ~TableAsArray(); • virtual void AddItem( Item * I ); • virtual void Clear(); • virtual unsigned GetCount() const; • virtual Item * GetItemPtr( unsigned i ) const; • virtual unsigned IndexOf( const Item * P ) const; • virtual void Sort();
Tablearr.h • friend ostream & operator <<( ostream & os, • const TableAsArray & T ); • private: • Item ** data; // array of pointers to Items • unsigned size; // allocation size • unsigned count; // number of Items • private: • void swap( Item * & p1, Item * & p2 ); • };
Tablearr.h • inline TableAsArray::~TableAsArray() • { Clear(); • } • inline unsigned TableAsArray::GetCount() const • { return count; • } • inline Item * TableAsArray::GetItemPtr( unsigned i ) const • { assert( i < count ); • return data[i]; • }
Item.cpp #include "item.h" ostream & operator <<( ostream & os, const Item & I ) { I.printOn( os ); return os; } istream & operator >>( istream & inp, Item & I ) { I.readFrom( inp ); return inp; }
Package.cpp #include "package.h" Package::Package() { Init();} Package::Package( long trackNumP, long originP, long destinP, long dateP, float costP, float weightP ) { SetTrackNum( trackNumP ); SetOrigin( originP ); SetDestination( destinP ); SetDate( dateP ); SetCost( costP ); SetWeight( weightP ); }
Package.cpp void Package::Init() { SetTrackNum( 0 ); SetOrigin( 0 ); SetDestination( 0 ); SetDate( 0 ); SetCost( 0.0f ); SetWeight( 0.0f ); } long Package::GetDestination() const { return destin;} long Package::GetTrackingNumber() const { return trackNum;} float Package::GetWeight() const { return weight;}