You are on page 1of 50

C/C++ Programming Techniques

ET2031/ ET2031E
Chapter 6: Inheritance

Lecturer: PhD. DO Thi Ngoc Diep


SCHOOL OF ELECTRICAL AND ELECTRONIC ENGINEERING
HANOI UNIVERSITY OF SCIENCE AND TECHNOLOGY
Content

• 6.1. Basic concepts


• 6.2. Polymorphism
• Virtual methods
• Abstract class
• 6.3. Multiple inheritance
• Virtual base class
• 6.4. Class Design

3
6.1. Basic concepts

4
Fundamental principles of OOT

Object-Oriented Technology

Polymorphism
Encapsulation
Abstraction

Inheritance

5
Basic concepts

• Reuse the source code:


• Structured programming: reuse the functions/procedures
• OOP: Many types of objects that have similar or related properties and
behaviors => How do we reuse the written class?
• How to reuse an existing class:
• Copy old class content to another class => Redundant and difficult to manage
when there are changes.
• Creating a new class is the collection of objects from existing classes =>
Aggregation
• Create a new class on the basis of developing from an existing class =>
Inheritance
• Advantages:
• Minimize effort and cost
• Improve software quality
• Enhance real world modeling capability
• Improve maintainability
Basic concepts

• Nature of inheritance
• Create a new class by developing an existing class
• The new class inherits what is already in the old class and develops new
features.
• Old class: Parent class, super class, base class
• New class: Child class, sub class, derived class
• Sub class
• is-a-kind-of super class
• Reuse by inheriting data elements and behaviors
of the super class
• Can be detailed to follow new definition
• Extension: Add new properties / behavior
• Redefinition (Method Overriding): Modifying
behavior inherited from the super class
Basic concepts

• Data object in memory


class X {
int x;
string str;

public:
X() {}
~X() {}
void printX() {}
};

class Y : public X {
int y;

public:
Y() {}
~Y() {}
void printY() {}
};

8
Constructor and Destructor in Inheritance

• Super class’ constructors and destructors cannot be inherited by sub classes


• Each sub class constructor must call a super class constructor
• otherwise it will implicitly call the default constructor, or constructor with no
parameter (if any), of the super class
• The sub class must call constructor of the super class in the initialization list

class Pet { class Bird {


string name; public:
public: Bird(bool canFly) {...}
Pet() {...} };
Pet(string name) {...}
}; class Eagle: public Bird {
public:
class Dog: public Pet { Eagle() {...} // error
... Eagle(): Bird(true) {...}
public: };
Dog() {...} // Pet()
Dog(string name): Pet(name) {...}
};

9
Constructor and Destructor in Inheritance

• Sub class's destructor:


• Only need to handle additional/new properties of the sub class
• The destructor of the classes will be called automatically in reverse order
from the sub class to the super class
• ~Dog()  ~Pet()
• ~Eagle()  ~Bird()

10
Basic concepts

• Inheritance classification
• Number of base classes:
• Single Inheritance: a sub class inherits only one super class
• Multiple inheritance: a sub class inherits from 2 or more super classes
• Inheritance style:
• private
• protected
• public
• Syntax:
class A {
// members of class A
};
class B : <inheritance_style> A {
// new members of class B
};
Reminder: Access modifier for members of class

• public: The properties or methods are accessible from outside the


class.
• private: Properties or methods that are only accessible through the
method of the class itself.
• protected: Properties or methods can not be accessed from
outside of the class except from the methods of sub classes.

Access modifier public protected private

Access from methods of the class itself Ok Ok Ok

Access from methods of sub class Ok Ok X

Access from other classes Ok X X

12
Inheritance style

• A sub class can inherit from the super class according to the
following styles of inheritance: public, protected, private (default).
• The access scope of the members of the super class changes within
the sub class depending on the style of inheritance.

Access modifier in super class


Access modifier in sub class
will change to ... public protected private

public public protected never inherited Unchanged


Inheritance style protected protected protected never inherited All protected
private private private never inherited All private

13
public inheritance style

class Employee { public


private:
string name; The access scope of member remains the
float salary; same, except the private is not accessible
public:
string getName() {...}
void pay() {...}

};

class Worker : public Employee{


private: Worker w;
int level; w.getName();
public: w.doWork();
void doWork() {...} w.pay();
void show() { w.salary = 10; // Error
cout << getName() w.show(); // Error
<< salary; // Error
}
};

14
public inheritance style

class Employee { public


private:
string name; The access scope of member remains the
float salary; same, except the private is not accessible
public:
string getName() {...}
void pay() {...}
float getSalary(){return salary;}
};

class Worker : public Employee{


private: Worker w;
int level; w.getName();
public: w.doWork();
void doWork() {...} w.pay();
void show() { w.getSalary(); // OK
cout << getName() w.show(); // OK
<< getSalary() ;
}
};

15
public inheritance style

class Employee { public


protected :
string name; The access scope of member remains the
float salary; same, except the private is not accessible
public:
string getName() {...}
void pay() {...}

};

class Worker : public Employee{


private:
int level; Worker w;
public: w.doWork();
void doWork() {...}
w.pay();
void show() {
cout << getName() w.name = "NV Tung"; // error
<< salary; cout << w.salary; // error
} cout << w.show(); // ok
};

16
private inheritance style

class LinkedList {
private: private
... All changes to private, except the
public: private is not accessible
void insertTail(int x) {...}
void insertHead(int x) {...}
void deleteHead() { ... }
void deleteTail() { ... }
int getHead() { ... }
int getTail() { ... }
...
};
Stack s;
class Stack : private LinkedList {
s.push(10);
public:
s.push(20);
void push(int x)
s.pop();
{ insertHead(x); }
int pop() {
s.insertTail(30); // error
int x = getHead(); // error
s.getTail();
deleteHead();
return x;
}
...
};

17
6.2. Polymorphism

18
Polymorphism concept

• Polymorphism: “one name, many forms”


• Describe an object in different ways
• For example:
• One person is considered as an Intern, or a Staff of a company. Intern is
inherited some features of Staff.
• Depend on this person is “treated” as an Intern or a Staff, the suitable
method is applied at a time.

• Perform an action in different ways


• For example:
• If you travel, you can choose a car, boat, or plane
• No matter what vehicle you go by, the result is the same: getting where you
need to go
• Different ways to perform a service

19
Polymorphism in programming

• Polymorphism in methods:
• Method with the same name, distinguished by list of parameters (method
overloading)
• ...
• Polymorphism in objects:
• Seeing objects in many different ways: one object has the ability to be acted
as other objects
• => An object can perform an action in many different ways

20
Pointer and reference variables to sub class object

class Base{
public:
const char* getName(){ return "Base"; }
};
class Derived : public Base{
public:
const char* getName() { return "Derived"; }
const char* getValueDoubled() { return "Value Doubled"; }
};
int main() derived
{ Inherited
Derived derived; rBase
Base &rBase = derived; members
Base *pBase = &derived; pBase New
cout << "derived is a " << derived.getName() << '\n';
cout << "rBase is a " << rBase.getName() << '\n';
members
cout << "pBase is a " << pBase->getName() << '\n';
return 0;
}
• rBase and pBase are declared as variables of Base class
derived is a Derived • rBase and pBase only "see" the members of the Base class
rBase is a Base • rBase and pBase cannot call getValueDoubled();
pBase is a Base

21
Pointer and reference variables to super class object

class Base{
public:
const char* getName(){ return "Base"; }
};
class Derived : public Base{
public:
int x = 10;
const char* getName() { return "Derived"; }
const char* getValueDoubled() { return "Value Doubled"; }
};
int main()
{
Base base;
Derived derived;
Derived &rDe = base; // error
Derived *pDe = (Derived *)&base;
cout << derived.x << '\n'; 10
cout << pDe->x << '\n'; // unsafe !!!
2661
return 0;
}

22
Polymorphism in methods

• Make different solutions using the same prototype


class Animal {
public: const char* speak() { return "???"; }};
class Cat: public Animal {
public: const char* speak() { return "Meow";}};
class Dog: public Animal {
public: const char* speak() { return "Woof"; }};

void report(Animal *pAnimal){ cout << " says " << pAnimal->speak() << '\n';}

int main()
{
Cat cat;
Dog dog;
Animal *pAnimal = &cat;
report(pAnimal) ; “Early binding” concept
pAnimal = &dog;
report(pAnimal);
return 0; void report(Cat &cat){
} cout << " says " << cat.speak() << '\n';}
? void report(Dog &dog){
cout << " says " << dog.speak() << '\n';}
...

23
Polymorphism in methods

• Make different solutions using the same prototype


using virtual method (overriding concept, late binding concept)
• for methods marked as virtual method:
• compiler delays the decision of method to call to runtime, instead of compile time
class Animal {
public: virtual const char* speak() { return "???"; }};
class Cat: public Animal {
public: virtual const char* speak() { return "Meow";}};
class Dog: public Animal {
public: virtual const char* speak() { return "Woof"; }};

void report(Animal *pAnimal){ cout << " says " << pAnimal->speak() << '\n';}
int main()
{
Cat cat;
Dog dog;
Animal *pAnimal = &cat;
report(pAnimal) ;
pAnimal = &dog;
report(pAnimal)
return 0;
}

24
Virtual method

• Call to a virtual method from an object: as normal


• Call to a virtual method from a pointer: depends on type of the object at
runtime not on the type at compile time
must have
class A { public: virtual void check();};
class B : public A {public: virtual void check();};
class C : public B {public: virtual void check();};
class D : public B {}; can be ignored

A a; B b; C c; D d;
a.check();b.check();c.check();d.check();

A *p;
p = &a; p->check(); // A::check();
p = &b; p->check(); // B::check();
p = &c; p->check(); // C::check();
p = &d; p->check(); // B::check();

void present(A *s){ s->check();}


present(&a); // A::check();
present(&b); // B::check();
present(&c); // C::check();
present(&d); // B::check();

25
Pure virtual method

• as a virtual method declaration


• the definition will be defined in the sub class
=> solve problems on different objects according to the same strategy
class Pet {
public:
virtual void say() = 0;
Pet* p[3] = {
};
new Dog(), new Cat(), new Cat() };
class Cat: public Pet {
for (int i=0; i<3; i++)
public:
p[i]->say();
virtual void say()
{ cout << "miao\n"; }
};
gruh
class Dog: public Pet { miao
public: miao
virtual void say()
{ cout << "gruh\n"; }
};

26
Abstract class

• A class that is used only as a base for other classes.


• No objects of this abstract class are ever created
• However, pointers and references to “objects” of the abstract class are still valid
• Abstract class contains pure virtual method
class Shape {
public: Shape p; // error
virtual void draw() = 0;
virtual void erase() = 0;
virtual void area() = 0; Circle c;
void redraw() { ... } Shape p2 = c; // error
}; Shape& p3 = c; // OK
Shape* p4 = &c; // OK
class Circle: public Shape {
public: void func(Shape s) {...} // error
...
virtual void draw() { ... }
void func(Shape& s) {...} // OK
virtual void erase() { ... } void func(Shape* s) {...} // OK
virtual void area() { ... }
};

27
Virtual destructor

• Needed when using pointer to base class

class ClassA { class ClassA {


public: public:
ClassA() { ... } ClassA() { ... }
~ClassA() { ... } virtual ~ClassA() { ... }
}; };

class ClassB: public ClassA { class ClassB: public ClassA {


public: public:
ClassB() { ... } ClassB() { ... }
~ClassB() { ... } virtual ~ClassB() { ... }
}; };

ClassB *b = new ClassB; ClassB *b = new ClassB;


ClassA *a =(ClassA *)new ClassB; ClassA *a =(ClassA *)new ClassB;

delete b; // ~ClassB, ~ClassA delete b; // ~ClassB, ~ClassA


delete a; // ~ClassA delete a; // ~ClassB, ~ClassA

28
Layout of an Object With Virtual Function

class X {
int x;
float xx;
static int count;

public:
X() {}
virtual ~X() {}

virtual void printAll() {}


void printInt() {}
void printFloat() {}
static void printCount() {}
};

http://www.vishalchovatiya.com/memory-layout-of-cpp-object/ 29
Layout of an Object With Virtual Function and Inheritance

class X {
int x;
string str;
public:
X() {}
virtual ~X() {}
virtual void printAll() {}
};

class Y : public X {
int y;
public:
Y() {}
~Y() {}
void printAll() {}
};

30
Resume

• Virtual functions ensure that the correct function is called for an object,
regardless of the type of reference (or pointer) used for function call.
• They are mainly used to achieve Runtime polymorphism
• Virtual functions cannot be static or friend function of another class.
• Virtual functions should be accessed using pointer or reference of base class
type to achieve run time polymorphism.
• The prototype of virtual functions should be same in base as well as derived
class.
• It is not mandatory for derived class to override (or re-define the virtual
function), in that case base class version of function is used.
• A class may have virtual destructor but it cannot have a virtual constructor.

31
6.3. Multiple inheritance

32
Multiple inheritance

• C++ allows a class to inherit from many different classes, at


different levels.
class Camera { class CellPhone:
public: public Camera,
void takePicture(); protected FMDevice,
... public Phone
}; {
public:
class FMDevice { void turnFMOn();
public: void turnFMOff();
void turnOn(); void setFMFreq(float f);
void turnOff(); ...
void setFreq(float f); };
...
};
CellPhone p;
class Phone { p.takePicture();
public: p.turnOn(); // error
void call(string num); p.turnFMOn();
... p.call("0912345678");
};

33
Virtual base class

• A sub class mentioned more than once in a super class can cause
the ambiguity  using a virtual base class
class A {
public: int a;
};
class B : public A {};
class C : public A {};
class D : public B, public C {};

D h;
h.a = 1; // error: ambiguity

class B : virtual public A {};


Class D will have only 1 sub class A
class C : virtual public A {};

34
Multiple inheritance

• Working with elements of the same name


• (1) specify the class name in the call C h; // class C
class A { public: void check();}; h.check(); // from C
class B : public A {public: void check();}; h.B::check(); //from B
class C : public B {public: void check();}; h.A::check(); //from A

• (2) note for un-virtual methods !


A *p, *q, *r; // declared as pointer of the class A
A a; p = &a;
B b; q = &b;
C c; r = &c;
p->check(); // A::check();
q->check(); // A::check();
r->check(); // A::check();

35
Layout of an Object With Virtual Function and Multiple Inheritances

class X {
public:
int x;
virtual ~X() {}
virtual void printX() {}
};

class Y {
public:
int y;
virtual ~Y() {}
virtual void printY() {}
};

class Z : public X, public Y {


public:
int z;
~Z() {}
void printX() {}
void printY() {}
void printZ() {}
};

36
6.4. Class Design

37
Class Design

• To manage the company's human resources, we can define classes according to the
working positions:

class Worker { class Manager { class Director {


private: private: private:
string name; string name; string name;
float salary; float salary; float salary;
int level; int dept; public:
public: public: string getName() {...}
string getName() {...} string getName() {...} void report() {...}
void pay() {...} void pay() {...} void pay() {...}
void doWork() {...} void manage() {...} ...
... ... };
}; };

• All 3 classes above have identical properties and functions in terms of content
 create an Employee class containing that common information for reuse

38
Class Design

class Worker { class Manager { class Director {


private: private: private:
string name; string name; string name;
float salary; float salary; float salary;
int level; int dept; public:
public: public: string getName() {...}
string getName() {...} string getName() {...} void report() {...}
void pay() {...} void pay() {...} void pay() {...}
void doWork() {...} void manage() {...} ...
... ... };
}; };

string name;
Super class float salary;
Employee string getName() {...}
void pay() {...}

Sub classes
Worker Manager Director
int level; int dept; void report(){...}
void doWork(){...} void manage(){...}

39
UML - Class diagram

• UML (Unified Modeling Language): a visual language for visualizing,


specifying, constructing, documenting the components of a software system
• Establish a unified way for building and “drawing” requirements following an
object-oriented design during software development
• Class Diagram: one of Static Structural Diagrams
• show the existence of classes and their relationships in the logical design of a system
• Class representation

40
UML - Class diagram

• Class: class name, attributes/properties, action/methods


• Italic: abstract members
• Underline: static members
• ALL_CAPS: final members
• Access modifier: (+, -, #)

41
UML - Class diagram

• Relationship between classes:


• Association: having connection with, using object from other class
• Multiplicity
• Navigability: specifies the direction of the link
• Constraint (constraint): has a condition on association

author

<Person>

Navigability

42
UML - Class diagram

• Relationship between classes:


• Association
• Type of association:
• Aggregation: describes the whole-part relationship, also known as the "is a part of"
relationship.
• Composition: is a form of aggregation, the part cannot exist if the whole is
destroyed.

• Generalization: Also known as “is a kind of”/inheritance relationship

Generalization

43
3.1.1 Symbols in class diagram

• Relationship between classes:


• Dependency: a set of suppliers provides something to the clients.
• Modification of the supplier may impact the client elements

https://www.uml-diagrams.org

44
UML - Class diagram

• Example
• Course registration system
Basic classes

CloseRegistrationForm Schedule CloseRegistrationController


- semester
+ open() + is registration open?() Professor
+ close registration() + commit() + close registration() - name
+ select alternate() - employeeID : UniqueId
+ remove offering() - hireDate
+ level() - status
+ cancel() - discipline
Student + get cost() - maxLoad
+ delete()
+ submit() + submitFinalGrade()
+ get tuition()
+ save() + acceptCourseOffering()
+ add schedule()
+ any conflicts?() + setMaxLoad()
+ get schedule()
+ create with offerings() + takeSabbatical()
+ delete schedule()
+ update with new selections() + teachClass()
+ has pre-requisites()

45
UML - Class diagram

• Example
• Course registration system
Simple class diagram

LoginForm RegistrationController
RegisterForCoursesForm 1
0..1
1 CloseRegistrationController
0..1
Schedule Professor
CloseRegistrationForm
0..*
0..*
instructor 0..1
1 0..4
Student
Course CourseOffering
0..*
CourseCatalogSystem
BillingSystem

46
UML - Object diagram

• Like class diagrams, instead of class diagrams, object diagrams


represent actual instances of classes and the relationships between
them.

Object/instance name

Class name

47
Exercises

1. Viết các lớp Shape (lớp trừu tượng) và các lớp con Circle, Square, Rectangle, Ellipse,
Sphere. Hãy thiết kế việc kế thừa sao cho hợp lý. Viết các hàm ảo tính diện tích hình.
2. Một Company có nhân viên gồm Director, Manager, và Worker. Mỗi nhân viên có tên,
mức lương khác nhau. Viết chương trình thực hiện việc thêm nhân viên, in thông tin
nhân viên, xóa toàn bộ nhân viên.

48
Exercises

1. Write a Shape class (an abstract class) and sub classes named Circle, Square, Rectangle,
Ellipse, Sphere. Design inheritance properly. Write virtual functions that calculate the
area of a shape.
2. A Company has employees consisting of Director, Manager, and Worker. Each employee
has a different name and salary. Write a program to add an array of employees, print
employee information, and delete all employees.

49
50

You might also like