Lab Manual 02 - OOP Concepts Review - 2
Lab Manual 02 - OOP Concepts Review - 2
Lahore Campus
Lab- 02 Manual
Lab Instructor: Riaz Ahmad
Department of Computer Science
Email: [email protected]
Inheritance represents “is-a” relationship in OOP i.e. any specific object is a type of a
more general class of object. For example, Train is a type of Vehicle
By design, a derived class should inherit all attributes and behaviors of its base class(es)
While declaring its own data fields a derived class can extend the features of its base
class(es)
While defining new functionality, a derived class can modify the behavior provided by
the base class(es)
Inheritance in OOP saves a lot of work and time. You can save additional work as some of the object
definitions(class) already exists. Time saving is due to the reason that much of the code has already been
written and tested.
Examples:
Note: Every object of derived class has an anonymous object of base class
Default constructor:
Default constructor is such constructor which either has no parameter or if it has some parameters these
have default values. The benefit of default constructor is that it can be used to create class object without
passing any argument.
We can avoid this error by calling base class non-default constructor in derived class
constructor initializer list by ourself.
Different Types of Inheritance
Example: Implementation of Single level Inheritance [CLO 2]
#include<iostream> class B:public A
using namespace std; {
int b;
class A public:
{ B(int j,int i):A(i)
int a; {
public: b=j;
A(int i) }
{ void show()
a=i; {
} cout<<"\nThe Value of b:"<<b;
void Display() }
{ };
cout<<"\nThe value of a:"<<a;
}
};
int main()
{
B b(4,5);
cout<<" B class";
b.Display();
b.show();
return 0;
}
Example: Implementation of Multilevel Inheritance [CLO 2]
#include<iostream class B:public A class
> using namespace { C:public B{
std; int b; int c;
publi public:
class A c: C()
{ B() {c
int a; { =0;
b=0; }
public:
A() } void setc(int
{ void setb(int i){ c=i;
a=0; i){ b=i; }
} } int
void seta(int int get_c()const{
i){ a=i; getb()const{ r return c;
} eturn b; }
int } void print(){
geta()const{ r void show() this-
eturn a; { >show();
} Display(); cout<<"\n The Value of
void Display() cout<<"\nThe Value of c:"<<get_c();
{ b:"<<getb();
}
cout<<"\nThe value of }
};
a:"<<geta(); };
}
};
int main()
{
C c;
c.seta(4)
;
c.setb(3);
c.setc(2);
c.print();
return 0;
}
Example: Implementation of Hierarchal Inheritance [CLO 2]
cout<<"\nThe B
class"; b.Display();
b.show();
cout<<" \n\n C
class"; c.Display();
c.show()
; return
0;
}
Association
Interaction of different objects in OO model (or in problem domain) is known as association. In object-
oriented model, objects interact with each other in order to perform some useful work, while modeling
these objects (entities) is done using the association. Usually, an object provides services to several other
objects. An object keeps association with other objects to delegate tasks. This association can be
represented with a line along an arrow head ( ) or without arrow head.
Kinds of Association:
There are two main types of association which are then further subdivided i.e
1. Class Association
2. Object Association
1. Class Association
Class association is implemented in terms of Inheritance. Inheritance implements
generalization/specialization relationship between objects. Inheritance is considered class association.
• In case of public inheritance it is “IS-A” relationship.
• In case of private inheritance, it is “Implemented in terms of” relationship.
This relationship ensures that public members of base class are available to derived class in case of public
inheritance.
When we create objects of classes in which we have implemented inheritance relationships we are forcing
the inheritance relationship between created objects. In this case the derived class objects will also contain
base class objects attributes and methods.
2. Object Association
It is the interaction of stand-alone objects of one class with other objects of anther class.
It can be of one of the following types,
• Simple Association
• Composition
• Aggregation
Yasir is a
friend of Ali
Ali is a friend
of Yasir
a. Binary Association
It associates objects of exactly two classes; it is denoted by a line, or an arrow between the
associated objects.
Example:
c. N-ary Association
An association between 3 or more classes its practical examples are very rare.
Composition
An object may be composed of other smaller objects, the relationship between the “part” objects
and the “whole” object is known as Composition, and Composition is represented by a line with
a filled-diamond head towards the composer object
Example – Composition of Ali
Example – Composition of Chair
Example I
Ali is made up of different body parts
They can’t exist independent of Ali
Example II
Chair’s body is made up of different parts
this->DeptName=name;
}
void show(){
cout<<"\n Department Name:"<<DeptName;
}
};
class University{
private:
string UName;
Department Dept;
public:
University(string name=""):UName{name}
{
}
void setDept(Department d){ Dept=d;
}
void display(){
cout<<"The University\t "<<UName<<"\t has Department \n";
Dept.show();
}
};
int main()
{
University U("UMT");
Department dpt("CS");
U.setDept(dpt);
U.display();
return 0;
}
Aggregation
An object may contain a collection (aggregate) of other objects, the relationship between the
container and the contained object is called aggregation, Aggregation is represented by a line
with unfilled-diamond head towards the container
Example – Aggregation
Example – Aggregation
Example I
Furniture is not an intrinsic part of room
Furniture can be shifted to another room, and so can exist independent of a particular room
Example II
A plant is not an intrinsic part of a garden
It can be planted in some other garden, and so can exist independent of a particular garden
this->id=id;
this->EmpName=name;
}
void show(){ cout<<"\
nEmployee ID:"<<id;
cout<<"\n Employee Name:"<<EmpName;
}
};
class company{
private:
string cmpName;
Employee *emp;
public:
company(string name="")
{ cmpName=name;
}
void setEMp(Employee *emp)
{ this->emp=emp;
}
void display(){
cout<<"The Company\t "<<cmpName<<"\t has Employee \n";
emp->show();
}
};
int main()
{
company cmp("Bata");
Employee emp(1234,"Ali
Ahmed"); cmp.setEMp(&emp);
cmp.display();
return 0;}
};
int main()
{
B b;
b.seta();
b.setb();
b.display();
b.show();
return 0;
}
Another important use of access specifiers is their role in the inheritance process. Considering
access specification in C++, inheritance can be private, protected, or public. Each type of inheritance has
specific rules to access base class’s data member(s), which have been explained below.
There are three types of inheritance
• Public
• Protected
• Private
If a class is derived from a base class with public specifier, then all public/protected member(s) of base
class become public/protected member(s) of derived class. However, private member(s) of base class are
never accessible from derived class directly.
If a class is derived from a base class with protected specifier, then all public/protected
member(s) of base class become protected member(s) of derived class. However, private
member(s) of base class are never accessible from derived class directly.
If a class is derived from a base class with private specifier, then all public/protected member(s)
of base class become private member(s) of derived class.
If the user does not specifies the type of inheritance then the default type is private Inheritance,
};
int main()
{
B b;
// b.display(); // Error we can not access
b.show();
return 0;
}
Private inheritance
#include <iostream> class B:private
A{ int b;
using namespace std; class public:
A{
B():A(){
private: b=7;
int a; }
public: void show(){
A(){ display(); //solution cout<<"\
a=8; n"<<b;
} }
void display(){
cout<<"\n"<<a; };
}
};
};
Private data members will NOT be accessible in any derived class or in main function.
Protected data members will become private data members in case of private inheritance and protected data
members of derived class in case of protected inheritance.
Function overloading
Function Overloading is the availability of various functions within a class that differ from each other in
function signature i.e. various functions share same name with different parameter types or number of
parameters. Inheritance is not necessarily required to overload functions within a program.
Function Overriding
Function Overriding, there must exists inheritance relationship between classes (i.e. base and derived) and
functions’ signature are also required to be same in both parent and child class(es). However, derived
class(es) redefine function(s) having signature similar to base class’s function(s).
Polymorphism:
It is Combination of Two Greek Words
Poly: Many
Morphism: Forms
Polymorphism allows an object reference variable or an object pointer to reference objects of different
types and to call the correct member Functions, depending upon the type of object being referenced.
There are two types polymorphism
1. Static /Compile time Polymorphism
It is also known as Early Binding
Example:
Function overloading and Operator overloading
2. Dynamic /Run time Polymorphism
It is also known as Late Binding
Example:
Virtual Function
Check the behavior of Base class pointer object, Even we are giving address of derive class
object but it is calling to base class function .This is because the compiler checks static type of
the object (means which class type object is calling the object) at compile and call function
according to the type of object. When function is call by seeing the type of the object this is
called compile time, early or static binding.
Upon calling func() with bPtr, Derived class func() will be invoked and output would be
“Derived Class Function”. In the absence of virtual keyword, func() of base would be called
each time. Hence, it can be concluded that virtual keyword allow a pointer of base class to call
appropriate function of any of its derived class to whom it is referencing. In this way, each time a
different function will be invoked with the same function call. With polymorphism, compiler
does not know which function to call at compile and thus appropriate function call is deferred to
runtime. At runtime, the type of object that a base class pointer is pointing is recognized to call
proper function. This is known as dynamic or late binding.
class Base
{
protected:
virtual void func() = 0;
};
Lab Manual: Data Structures and Algorithms
Lab Tasks
Task 1:
Consider a base class named Employee and its derived classes HourlyEmployee and
PermanentEmployee while taking into account the following criteria.
Employee class has two data fields i.e. a name (of type string) and specific
empID (of type integer)
Both classes (HourlyEmployee and PermanentEmployee) have an attribute
named hourlyIncome
Both classes (HourlyEmployee and PermanentEmployee) have three-argument
constructor to initialize the hourlyIncome as well as data fields of the base class
Class HourlyEmployee has a function named calculate_the_hourly_income to
calculate the income of an employee for the actual number of hours he or she
worked. One hour income is Rs. 150
Similarly, PermanentEmployee class has function named calculate_the_income
to calculate the income of an employee that gets paid the salary for exact 240
hours, no matter how many actual hours he or she worked. Again, one hour
salary is Rs. 150.
Implement all class definitions with their respective constructors to initialize all data
members and functions to compute the total income of an employee. In the main()
function, create an instance of both classes (i.e. HourlyEmployee and
PermanentEmployee) and test the working of functions that calculate total income of
an employee.
Task 2:
The person has birthday. The person class has following behavior and attributes
He has attributes name and city, Birthday
Design parameterize constructor to initialize with user defined values
Design Display function to show the person
information. The
Birthday class has following attributes
Task 4:
NoteBook is the base class that holds
data fields named manufacturerID (of integer type) and manufacturerName (of
string type)
A two-argument constructor to initialize data-fields with user-defined values
Appropriate accessor and mutator functions to set and get values of data
fields Derive two classes from the NoteBook class:
ENotebook, which contains an attribute size of integer type and a setter member
function to set size value
PaperNoteBook, which contains an instance variable named totalPages along
with a member function to
set total number of pages in a certain paper notebook object
Both derived classes have function display to show all data field values (including
values inherited from the base class).
In the main() function, create objects of ENoteBook and PaperNoteBook classes and show the
advantages of using protected access specifier.
Tasks 5
A class named Desktop inherits Computer class and adds fields representing
color, monitor size, and processor type and
Override function named show() to display values of its all attributes
A class named Laptop inherits Computer class and adds fields representing
color, size, weight, and processor type and
Override function named show() to display values of its all attributes
Write a main() function that instantiates objects of derived classes to access respective show() function
using dynamic binding.
Task 6:
ADT: NumDays