abstract and polymorphism

10
Programming for MSc Part II Part 2: OOP in C++ (e) Polymorphism and Abstract Classes The Is-A Relationship A parent class is its children’s smallest common denominator Every child must have the parent’s methods and data objects Every child is a parent, too, as it shares its properties Example: #include <iostrea m> class Parent { public: void print (void) { cout << "Parentprint.\n"; } }; class Child : public Pare nt { }; void pr int_parent (Parent &p) { p.print (); } in t main (void) { Child c; // Is also a Parent! print_parent (c); // Parent::print() is called return 0; } Herbert Mar tin Dietz e <[email protected]> 28

Upload: jayantbildani

Post on 07-Apr-2018

217 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Abstract and Polymorphism

8/6/2019 Abstract and Polymorphism

http://slidepdf.com/reader/full/abstract-and-polymorphism 1/10

Programming for MSc Part II Part 2: OOP in C++

(e) Polymorphism and Abstract Classes

The Is-A Relationship

• A parent class is its children’s smallest common denominator

• Every child must  have the parent’s methods and data objects

• Every child is a parent, too, as it shares its properties

Example:

#include <iostream>

class Parent {

public:

void print (void) { cout << "Parentprint.\n"; }

};

class Child : public Parent { };

void print_parent (Parent &p) { p.print (); }

int main (void)

{

Child c; // Is also a Parent!

print_parent (c); // Parent::print() is called

return 0;

}

Herbert Martin Dietze <[email protected]> 28

Page 2: Abstract and Polymorphism

8/6/2019 Abstract and Polymorphism

http://slidepdf.com/reader/full/abstract-and-polymorphism 2/10

Programming for MSc Part II Part 2: OOP in C++ — Polymorphism and Abstract Classes

Static method selection

• Normally method calls are resolved at compilation time

• How do is-a relationships handle overwritten methods?

Here the method overwritten by Child will not be called, because

the function print parent() only knows about the Parent:

#include <iostream>

class Parent {

public: // Defines the default print() method

void print (void) { cout << "Parentprint.\n"; }

};

class Child : public Parent {

public: // Overwrites the parent’s print() method

void print (void) { cout << Childprint.\n"; }

};

void print_parent (Parent &p) { p.print (); }

int main (void)

{

Child c; // Is also a Parent!

print_parent (c); // Parent::print() is called

return 0;

}

Herbert Martin Dietze <[email protected]> 29

Page 3: Abstract and Polymorphism

8/6/2019 Abstract and Polymorphism

http://slidepdf.com/reader/full/abstract-and-polymorphism 3/10

Programming for MSc Part II Part 2: OOP in C++ — Polymorphism and Abstract Classes

Dynamic Binding

• In C++, for dynamic binding  methods are declared virtual

• virtual methods are chosen at runtime

• A class with virtual methods needs a virtual Destructor!

Example:

#include <iostream>using namespace std;

class Parent {

public:

virtual ~Parent (void) {}

virtual void print (void)

{ cout << "Parent::print()\n"; }

};

class Child : public Parent {

public:

virtual ~Child (void) {}

virtual void print (void)

{ cout << "Child::print()\n"; }

};

void print_parent (Parent &p) { p.print (); }

int main (void) {

Child c;

print_parent (c); // Child::print() is called,

return 0; // because c is a Child and

} // print() is virtual

Herbert Martin Dietze <[email protected]> 30

Page 4: Abstract and Polymorphism

8/6/2019 Abstract and Polymorphism

http://slidepdf.com/reader/full/abstract-and-polymorphism 4/10

Programming for MSc Part II Part 2: OOP in C++ — Polymorphism and Abstract Classes

Polymorphism

• Dynamic Binding  is required for Polymorphism

• Polymorphism (Greek, having multiple forms ) stands for

having different behaviours for one method name

• In the last example, every child has its own print() method

Example:

class Motorcycle {

public:

virtual void print (void) { cout << "MC\n"; }

virtual ~Motorcycle {}

};

class SidecarCycle : public Motorcycle {

public:

virtual void print (void) { cout << "SC\n"; }

virtual ~SidecarCycle {}

};

void print_cycle (Motorcycle &m) { m.print (); }

int main (void) {Motorcycle m;

SidecarCycle s;

print_cycle (m); // Motorcycle::print ()

print_cycle (s); // SicecarCycle::print ()

return 0;

}

Herbert Martin Dietze <[email protected]> 31

Page 5: Abstract and Polymorphism

8/6/2019 Abstract and Polymorphism

http://slidepdf.com/reader/full/abstract-and-polymorphism 5/10

Programming for MSc Part II Part 2: OOP in C++ — Polymorphism and Abstract Classes

Abstract Classes

• Sometimes a class does not represent anything real 

• Still it may make sense to create such a class

• All derived classes will inherit its code, thus the code has to

be written only once

• We call a class that we cannot create objects of  Abstract 

• For example, there is no concrete vehicle , thus the classVehicle will be abstract

• Concrete derived classes, such as Car or Motorcycle may

inherit the code for wheels, seats, engines, ...

• Another reason is to get consistent behaviour for same things

−→ A wheel will thus always behave the same

• Often most of the work goes into the abstract parent class

Abstract Methods

• An abstract class may not know how a method can be

implemented

• Still that method must be there• An Abstract Method  is declared  in a base class and must  be

implemented by all classes derived from it

• Why? The (abstract) base class represents the concept while

the derived classes are “only” the implementations

Herbert Martin Dietze <[email protected]> 32

Page 6: Abstract and Polymorphism

8/6/2019 Abstract and Polymorphism

http://slidepdf.com/reader/full/abstract-and-polymorphism 6/10

Programming for MSc Part II Part 2: OOP in C++ — Polymorphism and Abstract Classes

Example

IntArray -ar: int-size: int

+IntArray(size:int)+~IntArray()-do_size(): int-do_resize(size:int): void-do_at(pos:int): int-do_to(pos:int,val:int): void

IntStack 

+isEmpty(): bool+first(): int+insert(value:int): void 

IAStack

-nvals: int

+IAStack()+~IAStack()

Such a stack could be created with code like this:

IntStack stack = new IAStack ();

An alternative implementation could be derived from a List class

instead of an IntArray. Applications don’t have to know how

this stack was implemented, they only know about the abstractclass IntStack:

void get_element (IntStack &stack);

For an implementation in C++, the three methods in IntStack

have to be declared virtual. They are most likely also abstract .

Herbert Martin Dietze <[email protected]> 33

Page 7: Abstract and Polymorphism

8/6/2019 Abstract and Polymorphism

http://slidepdf.com/reader/full/abstract-and-polymorphism 7/10

Programming for MSc Part II Part 2: OOP in C++ — Polymorphism and Abstract Classes

Parent classes as Interfaces

• Another application for abstract classes are interfaces 

• An interface specifies one or more properties  rather than a

complete object

• Example: A class Printable may contain not more than a

print() method

• Every class derived from it now has such a print() method

• Think how easy it may get to implement printing on a printer

for different document types!

• An interface may not contain any implementation at all!

• In the previous example, the IntStack class is an interface

Abstract Classes and Methods in C++

• In C++, a method is abstract if it is declated virtual and 

initialized to 0, like this:

virtual void foo (void) = 0;

• In C++, a class containing one or more abstract methods is

automatically an abstract class

• The C++ compiler does not allow creating objects fromabstract classes

Abstract Classes and Methods in OMT Diagrams

In OMT diagrams, italic fonts are used for names of abstract

classes or methods.

Herbert Martin Dietze <[email protected]> 34

Page 8: Abstract and Polymorphism

8/6/2019 Abstract and Polymorphism

http://slidepdf.com/reader/full/abstract-and-polymorphism 8/10

Programming for MSc Part II Part 2: OOP in C++ — Polymorphism and Abstract Classes

A longer example:

Different document types have different properties. Still we may

want to use them in the same way (e.g. printing). Also some

documents contain multimedia elements, like images (found e.g.

in HTML or Word documents).

/* Part 1: images in documents */

/* classes for images and lists of images */

class Image {

// some methods and data objects

};

class ImageList {

// some methods and data objects

};

/* abstract class for objects that contain

* one or more images */

class HasImages {

protected:

ImageList *images;

virtual void setImages (void) = 0;public:

HasImages (void);

virtual ~HasImages (void);

bool hasMore (void);

Image *next (void);

};

Herbert Martin Dietze <[email protected]> 35

Page 9: Abstract and Polymorphism

8/6/2019 Abstract and Polymorphism

http://slidepdf.com/reader/full/abstract-and-polymorphism 9/10

Programming for MSc Part II Part 2: OOP in C++ — Polymorphism and Abstract Classes

/* Part 2a: printing */

/* interface for documents that can

* be printed */

class Printable {

public

virtual void print (void) = 0;

};

/* Part 2b: different document types */

class TextFile : public printable {

public:

TextFile (char *name);

virtual ~TextFile (void);

virtual void print (void);};

class HtmlFile

: public TextFile, public HasImages {

protected:

virtual void setImages (void);

public:

HtmlFile (char *name);

virtual ~HtmlFile (void);

virtual void print (void);

};

Herbert Martin Dietze <[email protected]> 36

Page 10: Abstract and Polymorphism

8/6/2019 Abstract and Polymorphism

http://slidepdf.com/reader/full/abstract-and-polymorphism 10/10

Programming for MSc Part II Part 2: OOP in C++ — Polymorphism and Abstract Classes

Using versus Inheritance

• Inheriting public methods can be a problem if they don’t fit

into a concept (e.g. array and queue)

• A good alternative can be using an object of that class instead

• The decision normally depends on what classes are available

• Inheritance is more powerful than using

• Using makes hiding of properties easier

Using objects in OMT diagrams

ElemStack-array: ElemArray-nelems: int

+ElemStack()+~ElemStack()+first(): Elem+append(e:Elem): void+isEmpty(): bool

ElemArray-ar: Elem*-size: int

+ElemArray(size:int)+~ElemArray()+at(pos:int): Elem+to(pos:int,val:Elem): void+size(): int

+resize(size:int): void

Herbert Martin Dietze <[email protected]> 37