Polymorphism Tiziana Ligorio 1 Todays Plan Inheritance Recap - - PowerPoint PPT Presentation

polymorphism
SMART_READER_LITE
LIVE PREVIEW

Polymorphism Tiziana Ligorio 1 Todays Plan Inheritance Recap - - PowerPoint PPT Presentation

Polymorphism Tiziana Ligorio 1 Todays Plan Inheritance Recap Polymorphism 2 Announcements Q: Why use dynamic memory allocation? 3 Inheritance Recap 4 Basic Inheritance class Printer { public:


slide-1
SLIDE 1

Polymorphism

Tiziana Ligorio

1

slide-2
SLIDE 2

Today’s Plan

Inheritance Recap Polymorphism

2

slide-3
SLIDE 3

Announcements

Q: Why use dynamic memory allocation?


3

slide-4
SLIDE 4

Inheritance Recap

4

slide-5
SLIDE 5

Basic Inheritance

class Printer
 {
 public:
 //Constructor, destructor 
 
 void setPaperSize(const int size);
 void setOrientation(const string& orientation);
 void changeCartridge();
 void printDocument(const string& document);
 private:
 // stuff here
 }; //end Printer class BatchPrinter: public Printer // inherit from printer
 {
 public: 
 //Constructor, destructor
 void addDocument(const string& document);
 void printAllDocuments();
 private:
 vector<string> documents; //Document queue
 }; //end BatchPrinter

5

slide-6
SLIDE 6

class GraphicsPrinter: public Printer // inherit from printer
 {
 public: 
 //Constructor, destructor
 void changeCartridge();
 void printDocument(const Picture& picture);
 
 private:
 //stuff here
 }; //end GraphicsPrinter

6

slide-7
SLIDE 7

Basic Inheritance

void initializePrinter(Printer& p)
 BatchPrinter batch;
 initizlizePrinter(batch); //legal because batch is-a printer Think of argument types as specifying minimum requirements Base class Superclass Derived Classes Subclasses is-a is-a

7

slide-8
SLIDE 8

Problem

class BatchPrinter: public Printer // inherit from printer
 {
 public: 
 //Constructor, destructor
 void addDocument(const string& document);
 void printAllDocuments();
 private:
 vector<string> documents; //Document queue
 }; //end BatchPrinter We would like to print all kinds of documents not just text
 documents should be able to store different types of documents

8

Can’t store different types of documents in printer queue

slide-9
SLIDE 9

Generalized Document

Whatever the type of document, a printer ultimately prints a grid of pixels Generalized Document should know how to convert itself into a printable format
 
 We want Document to be an interface => not concerned with implementation details

9

slide-10
SLIDE 10

10

Document Document Document Document

Document::convertToPixelArray()
 printPixelArray()

printAllDocuments()

slide-11
SLIDE 11

Polymorphism

11

slide-12
SLIDE 12

class BatchPrinter: public Printer // inherit from printer
 {
 public: 
 //Constructor, destructor
 void addDocument(const Document* document);
 void printAllDocuments();
 private:
 vector<Document*> documents; //Document queue
 }; //end BatchPrinter

12

slide-13
SLIDE 13

class Document:
 {
 public: 
 //Constructor, destructor
 virtual void convertToPixelArray() const = 0;
 virtual int getPriority() const = 0;
 
 private:
 //stuff here
 }; //end Document This function has no implementation** I’ll explain this next **odd syntax due to historical/political reasons, explained in quote later

13

Abstract Class!

slide-14
SLIDE 14

class TextDocument: public Document// inherit from Document
 {
 public: 
 //Constructor, destructor
 virtual void convertToPixelArray() const override;
 virtual int getPriority() const override; 
 
 void setFont(const string& font); //text-specific formatting
 void setSize(int size); private:
 //stuff here
 }; //end TextDocument Have implementation

14

slide-15
SLIDE 15

class TextDocument: public Document class GraphicsDocument: public Document class PortableFormatDocument: public Document class SpreadsheetDocument: public Document

15

slide-16
SLIDE 16

But how does compiler know whose convertToPixelArray() to call? TextDocument::convertToPixelArray?
 GraphicsDocument::convertToPixelArray?

16

GraphicsDocume TextDocument TextDocument MySpecialDocument

slide-17
SLIDE 17

Where are we going?

I want to store all kinds of documents in my BatchPrinter queue I want to access the correct convertToPixelArray() method specific to each different document type

17

slide-18
SLIDE 18

BatchPrinter myBatchPrinter; Document* myTextDocument = new TextDocument;
 Document* myGraphicsDocument = new GraphicsDocument;
 
 //do stuff myBatchPrinter.addDocument(myTextDocument)
 myBatchPrinter.addDocument(myGraphicsDocument) myBatchPrinter.printAllDocuments();
 
 myTextDocument->convertToPixelArray();
 myGraphicsDocument->convertToPixelArray();

TextDocument is-a Document GraphicsDocument is-a Document We can point to objects of derived class using pointers to base class We store in printer queue pointers to Document but really can access any derived class document convertToPixelArray is marked virtual so the appropriate function call is determined at runtime

18

main()

slide-19
SLIDE 19

Late Binding via Virtual Functions

Avoid statically binding function calls at compile time Must declare functions as virtual for late binding

19

slide-20
SLIDE 20

Polymorphism

We just saw an example of polymorphism (literally many forms) With virtual functions the outcome of an operation is determined at execution time With basic inheritance we were just saving ourselves the trouble of re-writing code

20

slide-21
SLIDE 21

Abstract Class

Pure virtual function (=0) has no implementation
 Abstract class 


  • Has at least one pure virtual function

  • Cannot be instantiated because does not have


implementation for some/all its member functions

Document myDocument; //Error!
 Document* myDocument = new Document;//Error!

21

slide-22
SLIDE 22

Bjarne Stroustrup

“The curious =0 syntax was chosen over the obvious alternative of introducing a new keyword pure or abstract because at the time I saw no chance of getting a new keyword accepted. Had I suggested pure, Release 2.0 would have shipped without abstract classes, I chose abstract classes. Rather than risking delay and incurring the certain fights over pure, I used the traditional C and C++ convention of using 0 to represent ‘not there’ ”

22

slide-23
SLIDE 23


 
 Base base_object;
 Derived derived_object;
 
 // stuff here base_object.someMethod(); //calls Base function
 derived_object.someMethod(); // calls Derived function - Overriding!!!
 
 
 


main()

23

Recap Basic Inheritance

Base someMethod(); . . . Derived someMethod() override; . . .

slide-24
SLIDE 24


 
 Base* base_ptr = new Base;
 Base* derived_ptr = new Derived;
 
 // stuff here base_ptr->someMethod(); //calls Base function
 derived_ptr->someMethod(); // ???
 
 
 


main()

24

Recap Polymorphism

Base someMethod(); . . . Derived someMethod() override; . . .

slide-25
SLIDE 25


 
 Base* base_ptr = new Base;
 Base* derived_ptr = new Derived;
 
 // stuff here base_ptr->someMethod(); // calls Base function
 derived_ptr->someMethod(); // calls Base function
 
 
 


Base someMethod(); . . . Derived someMethod() override; . . .

main()

25

Recap Polymorphism

slide-26
SLIDE 26


 
 Base* base_ptr = new Base;
 Base* derived_ptr = new Derived;
 
 // stuff here base_ptr->someMethod(); //calls Base function
 derived_ptr->someMethod(); // call Derived function - LATE BINDING!!!!
 
 
 


Base virtual someMethod(); . . . Derived someMethod() override; . . .

main()

26

Recap Polymorphism

slide-27
SLIDE 27

class Document:
 {
 public: 
 //Constructor, destructor
 virtual void convertToPixelArray() const = 0;
 virtual int getPriority() const = 0;
 
 private:
 //stuff here
 }; //end Document This function has no implementation**

27

Recap Abstract Class

slide-28
SLIDE 28

Polymorphism without abstraction

Superclass need not be abstract Virtual functions in superclass need not be pure virtual

28

slide-29
SLIDE 29

class InexperiencedSkater: public Skater
 {
 public:
 //constructor, destructor
 virtual void slowDown() override; 
 private:
 //stuff here
 }; //end InexperiencedSkater
 
 
 void InexperiencedSkater::slowDown()
 {
 fallDown();
 } //end slowDown

Polymorphism without Abstract Classes

class Skater
 {
 public:
 //constructor, destructor
 virtual void slowDown(); 
 //virtual, not pure
 
 private:
 //stuff here
 }; //end Skater 
 
 void Skater::slowDown() 
 {
 applyBreaks();
 } //end slowDown

29

implementation does not have virtual or

  • verride keyword
slide-30
SLIDE 30

Polymorphism without Abstract Classes

Skater* firstSkater = new Skater;
 firstSkater->slowDown(); // applyBreaks() Skater* secondSkater = new InexperiencedSkater;
 secondSkater->slowDown(); // fallDown() - LATE BINDING!

30

main()

slide-31
SLIDE 31

Polymorphism without Abstract Classes

Need not override non-pure virtual functions

class StuntSkater: public Skater
 {
 public:
 //constructor, destructor - note no mention of slowDown
 void frontFlip(); 
 void backFlip(); 
 private:
 //stuff here
 }; //end StuntSkater
 
 
 // stuff here
 
 
 Skater* stunt_skater = new StuntSkater;
 stunt_skater->slowDown(); // applyBreaks()

31

slide-32
SLIDE 32

Warning

class NotVirtual
 {
 public:
 void notAVirtualFunction();
 }; //end NotVirtual class NotVirtualDerived: public NotVirtual
 {
 public:
 void notAVirtualFunction() override;
 }; //end NotVirtualDerived
 
 
 
 NotVirtual* nv = new NotVirtualDerived;
 nv->notAVirtualFunction(); // OUCH!!! calls NotVirtual’s member
 // instead of NotVirtualDerived’s member

When using pointers to base class, to let derived classes

  • verride functions in base

class must make the base class’s function virtual

32

slide-33
SLIDE 33

More design considerations

Back to Document class Assume we realize all types of documents have width and height data members Makes sense to move them into base class Don’t want client to have direct access to data members

33

slide-34
SLIDE 34

class Document:
 {
 public: 
 //Constructor, destructor
 virtual void convertToPixelArray() const = 0;
 virtual int getPriority() const = 0;
 
 private:
 int width, height; //Problem!!!
 //stuff here
 }; //end Document

34

slide-35
SLIDE 35

protected Access in Base Class

class Document:
 {
 public: 
 //Constructor, destructor
 virtual void convertToPixelArray() const = 0;
 virtual int getPriority() const = 0;
 
 protected:
 int width, height; 
 //stuff here private:
 //stuff here
 }; //end Document

35

slide-36
SLIDE 36

Access Specifiers Base Class members

public
 accessible by everyone private
 accessible within class and by friends protected
 accessible within class, by friends and by derived classes

36

slide-37
SLIDE 37

Access Specifiers for Inheritance

class Derived: public Base
 {
 public: 
 //Stuff here
 
 
 private:
 //Stuff here 
 }; //end Derived

37

slide-38
SLIDE 38

Inheritance accessibility

Access in Base Class Inheritance Method Access in Derived Class public public public protected protected private no access public protected protected protected protected private no access public private private protected private private no access

We will not discuss the details of protected and private inheritance in this course is-a is-implemented-as is-implemented-and

  • inherited-as

38

slide-39
SLIDE 39
  • verride specifier

Explicitly tell compiler you mean to override a function Compiler will check! Also self-documenting

class BaseClass
 {
 virtual void f(int);
 };
 
 class DerivedClass: public BaseClass
 {
 virtual void f(float) override; //Compile-time error
 };

39

slide-40
SLIDE 40

final specifier

  • Prevents inheritance

  • Prevents deriving classes from overriding methods

class A
 {
 virtual void f();
 };
 
 class B : public A
 {
 void f() final override; //cannot override f()
 };
 
 class C: public B final //cannot inherit from C
 {
 void f() override; //Error, f is final!
 } class D: public C{} //Error C is final!

40

slide-41
SLIDE 41

Runtime Costs of Virtual Functions

41

Function call overhead


  • C++ maintains virtual function

tables that store pointers to each virtual function 


  • Determine which function to call

at execution time by looking-up v-table of object being pointed to Clever! But still
 Slower
 Extra space for v-tables Overhead -> mark individual functions virtual to take advantage of polymorphism only when appropriate Fully polymorphic inheritance would be overkill in most cases

slide-42
SLIDE 42

Recap

Polymorphism -> virtual functions Pure vs non-pure virtual functions Polymorphism with or without abstract classes

  • verride and final

Overhead

42

slide-43
SLIDE 43

Review Questions

43

slide-44
SLIDE 44

Polymorphism Recap

Base-class pointer to Derived class Determine behavior at runtime (late binding) HOW? virtual WHY? store different type of (Derived) objects in same container and retain access to each object’s distinct behavior

44

slide-45
SLIDE 45

Review Questions

What is OOP?

45

slide-46
SLIDE 46

Review Questions

What is an ADT?

46

slide-47
SLIDE 47

Review Questions

Why dynamic memory allocation?

When would you use it? What problems does it solve?

47

slide-48
SLIDE 48

Review Questions

What does final mean?

48

slide-49
SLIDE 49

Review Questions

How is basic inheritance different from polymorphism?

49

slide-50
SLIDE 50

Review Questions

Why Inheritance?

When would you use it? What problems does it solve?

50

slide-51
SLIDE 51

Review Questions

What is the overhead in Polymorphism?

51

slide-52
SLIDE 52

Review Questions

What is Information hiding?

52