inheritance in our daily lives we use the concept of classes divided into subclasses, for example...

45
Inheritance • In our daily lives we use the concept of classes divided into subclasses, for example vehicles are divided into cars, trucks, buses and motor cycles. • The principle in this sort of division is that each sub-class shares some common features with the base class from which it is derived, but also has its own particular features. Vehicle wheels engine Car wheels engine trunk Truck wheels engine trailer trunk trailer base class sub-classes or derived classes

Post on 19-Dec-2015

223 views

Category:

Documents


3 download

TRANSCRIPT

Page 1: Inheritance In our daily lives we use the concept of classes divided into subclasses, for example vehicles are divided into cars, trucks, buses and motor

Inheritance• In our daily lives we use the concept of classes divided into subclasses, for example vehicles are divided into cars, trucks, buses and motor cycles.• The principle in this sort of division is that each sub-class shares some common features with the base class from which it is derived, but also has its own particular features.

Vehiclewheelsengine

Carwheelsenginetrunk

Truck

wheelsenginetrailertrunk trailer

base class

sub-classes orderived classes

Page 2: Inheritance In our daily lives we use the concept of classes divided into subclasses, for example vehicles are divided into cars, trucks, buses and motor

Base Class Dateclass Date // declares class name{ private: int day, month, year; // member data public: // member functions void Date(int d, int m, int y); // constructor Date operator+(int days); Date& operator++(); int operator-(Date &date); bool LeapYear(); int DaysInMonth(); void Display();};

Page 3: Inheritance In our daily lives we use the concept of classes divided into subclasses, for example vehicles are divided into cars, trucks, buses and motor

Derived Class DateTimeclass DateTime : public Date // derived from base class Date

{

private:

int hour, minutes; // additional member data

public: // additional member functions

void DateTime(int d, int m, int y, int h, int mi); // constructor

void SetTime(int h, int m);

void AddMinutes(int m);

void AddHours(int h);

void Display(); // overrides Date::Display()

};

Page 4: Inheritance In our daily lives we use the concept of classes divided into subclasses, for example vehicles are divided into cars, trucks, buses and motor

Accessing Base Class Members

The access specifier private, protected and public specify which objects are allowed to access members of the base class

private: This member is only accessible within the

base class. protected:

This member is accessible within the base class and its derived classes.

public: Every object of the class outside the class

definition has access to this member

Page 5: Inheritance In our daily lives we use the concept of classes divided into subclasses, for example vehicles are divided into cars, trucks, buses and motor

Accessing Base Class Members

Base class

private:

protected:

public:

Derived class

private:

protected:

public:

Derived object; Base object;

Page 6: Inheritance In our daily lives we use the concept of classes divided into subclasses, for example vehicles are divided into cars, trucks, buses and motor

Inheritance vs. Composition

• Composition: • Composition is building objects from parts. • Composition denotes a has-a relationship• Composition is defined on the object level.• Example: A Car has an Engine

• Generalization:• Generalization is a relationship defined at the class

level not the object level, which means that all objects of this class must obey the relationship.

• Generalization denotes a is-a-kind-of relationship.• Example: A Car is a kind of Vehicle.

Page 7: Inheritance In our daily lives we use the concept of classes divided into subclasses, for example vehicles are divided into cars, trucks, buses and motor

Inheritance Vehcie/Engine

class Engine

{

void StartEngine();

};

class Vehicle : public Engine // bad design

{

};

Vehicle volvo;

volvo.StartEngine();

Page 8: Inheritance In our daily lives we use the concept of classes divided into subclasses, for example vehicles are divided into cars, trucks, buses and motor

Composition Vehicle/Engine

class Engine

{

void StartEngine();

};

class Vehicle : public Engine

{

private:

Engine engine;

public:

void Start() { engine.StartEngine(); }

};

Page 9: Inheritance In our daily lives we use the concept of classes divided into subclasses, for example vehicles are divided into cars, trucks, buses and motor

Virtual Functions

Virtual functions allow the re-definition of base class functions in the derived class

The program decides at run-time not at compile time which version of a function is called (dynamic binding)

When virtual functions are used, a program that appears to be calling a function of one class may in reality be calling a function of a different class

Page 10: Inheritance In our daily lives we use the concept of classes divided into subclasses, for example vehicles are divided into cars, trucks, buses and motor

Static Binding

class Animal

{

protected;

string str;

public:

Animal(const string s) : str(s) {};

void Display() { cout << ”Animal : ” << str << endl; }

// non-virtual function, static binding

};

Page 11: Inheritance In our daily lives we use the concept of classes divided into subclasses, for example vehicles are divided into cars, trucks, buses and motor

Derived Classes

class Dog : public Animal

{

public:

Dog(const string s) : Animal(s) {};

void Display() { cout << ”Dog : ” << str << endl; }

};

class Cat : public Animal

{

public:

Cat(const string s) : Animal(s) {};

void Display() { cout << ”Cat : ” << str << endl; }

};

Page 12: Inheritance In our daily lives we use the concept of classes divided into subclasses, for example vehicles are divided into cars, trucks, buses and motor

Static Binding

Animal *zoo[3]; // defines an array of pointers to Animal

Animal animal(”Flipper”); // creates an Animal object

Dog dog(”Lassie”); // creates a Dog object

Cat cat(”Jerry”); // creates a Cat object

zoo[0] = &animal; // pointer zoo[0] points to animal

zoo[1] = &dog; // pointer zoo[0] points to animal

zoo[2] = &cat; // pointer zoo[0] points to animal

for (int i=0; i<3; i++)

zoo[i]->Display(); // static binding to Animal::Display()

Output:

Animal : Flipper

Animal : Lassy

Animal : Jerry

Page 13: Inheritance In our daily lives we use the concept of classes divided into subclasses, for example vehicles are divided into cars, trucks, buses and motor

Static BindingAnimal

Display()zoo[0]->Display();

zoo[1]->Display();

zoo[2]->Display();

Dog

Display()

Cat

Display()

Page 14: Inheritance In our daily lives we use the concept of classes divided into subclasses, for example vehicles are divided into cars, trucks, buses and motor

Virtual Function

class Animal

{

protected;

string str;

public:

Animal(const string s) : str(s) {};

virtual void Display() { cout << ”Animal : ” << str << endl; }

// virtual function, dynamic binding

};

Page 15: Inheritance In our daily lives we use the concept of classes divided into subclasses, for example vehicles are divided into cars, trucks, buses and motor

Dynamic Binding

Animal *zoo[3]; // defines an array of pointers to Animalzoo[0] = new Animal(”Flipper”); // creates an Animal objectzoo[1] = new Dog(”Lassie”); // creates a Dog objectzoo[2] = new Cat(”Jerry”); // creates a Cat objectfor (int i=0; i<3; i++)

zoo[i]->Display(); // dynamic binding to either // Animal::Display(), Dog::Display() or Cat::Display()

Output:Animal : FlipperDog : LassyCat : Jerry

Page 16: Inheritance In our daily lives we use the concept of classes divided into subclasses, for example vehicles are divided into cars, trucks, buses and motor

Dynamic BindingAnimal

Display()zoo[0]->Display();

zoo[1]->Display();

zoo[2]->Display();

Dog

Display()

Cat

Display()

Page 17: Inheritance In our daily lives we use the concept of classes divided into subclasses, for example vehicles are divided into cars, trucks, buses and motor

Dynamic Binding with References

void f(Animal& a){ cout << ”This is an ”; a.Display();}

Animal animal(”Flipper”);Dog dog(”Lassie”);Cat cat(”Jerry”);f(animal);f(dog);f(cat);

Page 18: Inheritance In our daily lives we use the concept of classes divided into subclasses, for example vehicles are divided into cars, trucks, buses and motor

Dynamic Binding

#include <vector>Dog d(”Lassie”);Animal *a=&d; // defines a pointer of Animal that points to dAnimal &someanimal=d; // OKAnimal &anyanimal; // ERROR reference must be initializedvector<Animals*> animals; // OKanimals.push_back(&d); // add element pointer to d

Page 19: Inheritance In our daily lives we use the concept of classes divided into subclasses, for example vehicles are divided into cars, trucks, buses and motor

Abstract Classes

Assume you have a class library for graphics objects. All classes like Circle, Rectangle, Line etc. inherit from a base class Shape.

Shape is an abstraction of properties that all graphical elements have in common.

But there will never be an object of the Shape class itself, we will only make specific shapes such as circles and triangles.

As class that only acts as a base class for other classes is called an abstract class.

Page 20: Inheritance In our daily lives we use the concept of classes divided into subclasses, for example vehicles are divided into cars, trucks, buses and motor

Pure Virtual Function

A base class becomes an abstract class if it contains at least one pure virtual function.

A pure virtual function remains undefined in the base class but has to be overloaded by its subclasses.

A pure virtual function must be overloaded by the subclass whereas a virtual function can be overloaded by subclasses.

A pure virtual function is one with the expression =0 added to the declaration.

Page 21: Inheritance In our daily lives we use the concept of classes divided into subclasses, for example vehicles are divided into cars, trucks, buses and motor

Graphic Operations

Move(dx,dy)dx,dy

Rotate(phi,P(x,y)) P(x,y)

RotateShape(phi)

P(x,y) Center()

Page 22: Inheritance In our daily lives we use the concept of classes divided into subclasses, for example vehicles are divided into cars, trucks, buses and motor

Abstract Base Class Shape

class Point;

class Shape // abstract base class

{

virtual void Draw()=0; // pure virtual function

virtual void Move(double dx, double dy)=0; // move figure

virtual void Rotate(double phi)=0; // rotate figure around P=(0,0)

virtual Point Center()=0; // return center of figure

virtual void Rotate(int phi, Point p); // non-virtual: rotate

virtual RotateShape(); // rotate around center of figure

// around a Point p by angle p)

};

Page 23: Inheritance In our daily lives we use the concept of classes divided into subclasses, for example vehicles are divided into cars, trucks, buses and motor

Abstract Base Class Shape

void Shape::RotateShape(double angle)

{

Rotate(angle,Center()); // rotate shape around its own center

}

void Shape::Rotate(double angle, Point p)

{

Move(-p.GetX(),-p.GetY()); // move Shape so P is in (0,0)

Rotate(angle); // rotate around P(0,0) by angle degrees

Move(p.GetX(),p.GetY()); // move Shape back to by x,y

}

Page 24: Inheritance In our daily lives we use the concept of classes divided into subclasses, for example vehicles are divided into cars, trucks, buses and motor

SubClass Pointclass Point : public Shape // subclass inherits from Shape

{

public:

Point(double nx, double ny) : x(nx), y(ny) {} // constructor

virtual void Draw(); // draw a point

virtual void Move(double dx, double dy) {x+=dx; y+=dy;}

virtual void RotateShape(double phi) {} // nothing happens

virtual void Rotate(double angle); // rotate P around (0,0)

virtual Point Center() {return *this;} // return center of point

double GetX() { return x;}; double GetY() { return y;}

private:

double x,y;

};

Page 25: Inheritance In our daily lives we use the concept of classes divided into subclasses, for example vehicles are divided into cars, trucks, buses and motor

SubClass Point#include <math.h>

virtual void Point::Rotate(double angle) // rotate P around (0,0)

{

double nx=(cos(angle)*x-sin(angle)*y);

double ny=(sin(angle)*x+cos(angle)*y);

x=nx;

y=ny;

}

virtual void Point::Draw()

{

cout << “<“ << x << “,“ << y << “>”; // ohhhh... how boring

}

Page 26: Inheritance In our daily lives we use the concept of classes divided into subclasses, for example vehicles are divided into cars, trucks, buses and motor

SubClass Lineclass Line : public Shape // subclass inherits from Shape

{

public:

Line(Point np1, Point np2) : p1(np1), p2(np2) {} // constructor

virtual void Draw(); // draw a line

virtual void Move(double dx, double dy);

virtual void Rotate(double angle); // rotate P around (0,0)

virtual Point Center() {return (p1+p2)/2.0;}

private:

Point p1,p2;

};

Page 27: Inheritance In our daily lives we use the concept of classes divided into subclasses, for example vehicles are divided into cars, trucks, buses and motor

SubClass Linevirtual void Line::Draw() {

p1.Draw();

p2.Draw();

}

void Line::Move(double dx, double dy) {

p1.Move(dx,dy);

p2.Move(dx,dy);

}

virtual void Line::Rotate(double angle) {

p1.Rotate(angle);

p2.Rotate(angle);

}

;

Page 28: Inheritance In our daily lives we use the concept of classes divided into subclasses, for example vehicles are divided into cars, trucks, buses and motor

Using Shapes

Shape *shapes[4]; // stores four pointers to shapes

shapes[0] = new Point(3.0,8.9);

Point p1(7.2,5.6);

Point p2(6.5,2.3);

Point p3(3.4,1.0);

shapes[1]= new Line(p1,p2);

shapes[2]=new Triangle(p1,p2,p3);

shapes[3]=new Rectangle(p2,p3,p1,*shapes[0]);

Page 29: Inheritance In our daily lives we use the concept of classes divided into subclasses, for example vehicles are divided into cars, trucks, buses and motor

Compound Shapeclass CompoundShape : public Shape

{

public:

CompoundShape(Point p) { center=p; }

void AddShape(Shape &s);

virtual void Draw();

virtual void RotateShape(double angle);

virtual Point Center() { return center; }

private:

vector<Shape *> shapes;

Point center;

};

Page 30: Inheritance In our daily lives we use the concept of classes divided into subclasses, for example vehicles are divided into cars, trucks, buses and motor

Compound Shapevoid CompoundShape::AddShape(Shape &s)

{

shapes.push_back(&s);

}

virtual void Draw()

{

vector<Shape*>::iterator iter;

for(iter=shapes.begin();iter!=shapes.end();iter++)

*iter->Draw(); // de-reference twice !!!

}

Page 31: Inheritance In our daily lives we use the concept of classes divided into subclasses, for example vehicles are divided into cars, trucks, buses and motor

Compound Shapevoid CompoundShape::RotateShape(double angle)

{

vector<Shape*>::iterator iter;

for(iter=shapes.begin();iter!=shapes.end();iter++)

*iter->Rotate(angle,Center());

// rotate around center of compound !!!

}

Page 32: Inheritance In our daily lives we use the concept of classes divided into subclasses, for example vehicles are divided into cars, trucks, buses and motor

Overloading Assignment

Using the assignment symbol a2=a1;

causes the compiler to copy the data from a1, member by member into a2. This is the default action of the assignment operator =.

However, there might be situations in which you want the assignment operator to behave differently, for example if your data member is a pointer to objects you might want to replicate the objects itself as well not just the pointers.

Page 33: Inheritance In our daily lives we use the concept of classes divided into subclasses, for example vehicles are divided into cars, trucks, buses and motor

Linked List Examplestruct link // one element of list{ int data; // data item link *next; // pointer to next element};

class linklist{ private:

link* first; // pointer to first link public:

linklist() { first = NULL;} // no argument constructor void additem(int d); // add data item (one link) void display(); // display all links}

Page 34: Inheritance In our daily lives we use the concept of classes divided into subclasses, for example vehicles are divided into cars, trucks, buses and motor

Linked List Examplevoid linklist::additem(int d) // add data item{ link* newlink = new link; // create a new link newlink->data = d; // give it data d newlink->next=first; // it points to the next link first = newlink; // now first points to this link}void linklist::display() // display all links{ link* current=first; // set ptr to first link while(current != NULL) // until ptr points beyond last link { cout << current->data << ” ”; // print data current=current->next; // move to next link } }

Page 35: Inheritance In our daily lives we use the concept of classes divided into subclasses, for example vehicles are divided into cars, trucks, buses and motor

Linked List Example

void linklist::deleteitem() // delete first data item{ link* tmp=first->next; // tmp to remember pointer to 2nd element delete first; // deletes first link from memory first=tmp; // old second element becomes new first element}

Page 36: Inheritance In our daily lives we use the concept of classes divided into subclasses, for example vehicles are divided into cars, trucks, buses and motor

Linked List Example Assume you assign one list to another, with

the default assignment operator only the pointer to the first link gets copied.

linklist l1;

l1.additem(3);

l1.additem(5);

l1.additem(2);

2 5 3l1

Page 37: Inheritance In our daily lives we use the concept of classes divided into subclasses, for example vehicles are divided into cars, trucks, buses and motor

Linked List Examplelinklist l1;

l1.additem(3);

l1.additem(5);

l1.additem(2);

linklist l2;

l2=l1;

2 5 3l1

l2

2 5 3l2

Page 38: Inheritance In our daily lives we use the concept of classes divided into subclasses, for example vehicles are divided into cars, trucks, buses and motor

Overloading Assignment

linklist& linklist::operator=(linklist &list) // assignment operator{ while (first !=NULL) // first empty list deleteitem();

link* current=list.first; // set ptr to first link while(current != NULL) // until ptr points beyond last link { additem(current->data); // print data current=current->next; // move to next link } first=current; return *this; }

Page 39: Inheritance In our daily lives we use the concept of classes divided into subclasses, for example vehicles are divided into cars, trucks, buses and motor

Murphy’s Lawlinklist l1;

l1.additem(3);

l1.additem(5);

l1.additem(2);

l1=l1; // ooouuuch !!!! l1 deletes itself

linklist& linklist::operator=(linklist &list) // assignment operator{ if (this == &list) // both arguments to = are the same object return *this; …}

Page 40: Inheritance In our daily lives we use the concept of classes divided into subclasses, for example vehicles are divided into cars, trucks, buses and motor

Copy Constructor You can define and at the same time initialize an object

to a value of another object with two kinds of statements.linklist l1(l2); // copy initialization

linklist l1=l2; // copy initialization not assignmentl1=l2; // assignment operator =

class linklist{ public:

linklist() { first = NULL;} linklist( linklist& list) { *this=list; } // copy constructor … };

Page 41: Inheritance In our daily lives we use the concept of classes divided into subclasses, for example vehicles are divided into cars, trucks, buses and motor

Multiple Inheritance

base class A

Feature B

Feature A

subclass

Feature B

Feature A

Feature C

Feature D

base class B

Feature D

Feature C

Page 42: Inheritance In our daily lives we use the concept of classes divided into subclasses, for example vehicles are divided into cars, trucks, buses and motor

Multiple Inheritance

class Date

{

private:

int day, month, year;

};

class Time

{

private:

int hours, minutes;

};

Page 43: Inheritance In our daily lives we use the concept of classes divided into subclasses, for example vehicles are divided into cars, trucks, buses and motor

Multiple Inheritance

class DateTime : public Date, public Time

{

public:

DateTime(int d, int m, int y, int h, int mi)

: Date(d,m,y), Time(h, mi) {};

};

Page 44: Inheritance In our daily lives we use the concept of classes divided into subclasses, for example vehicles are divided into cars, trucks, buses and motor

Ambiguity in Multiple Inheritance

class Date

{

void add(int days);

};

class Time

{

void add(int minutes);

};

DateTime dt(13,2,1998,23,10);

dt.add(3); // ambiguous -- will not compile

dt.Date::add(4); // uses add of class Date

dt.Time::add(5); // uses add of class Time

Page 45: Inheritance In our daily lives we use the concept of classes divided into subclasses, for example vehicles are divided into cars, trucks, buses and motor

Ambiguity in Multiple Inheritance

class A { public: void F(); };

class B : public A { …};

class C : public A { …};

class D : public B, public C {};

D d;

d.F(); // ambiguous - won´t compile

class A

class B class C

class D

diamond shapedinheritance tree