LAB 7 OOP
LAB 7 OOP
(LAB-07)
Reusability I
(The protected Access Specifier and Types of Inheritance)
1
Lab 07: The protected Access Specifier and Types of
Inheritance in C++
1. Introduction
So far, you have learned the importance and use of two (public and private) access specifiers
within class(es) of C++. You know that a class’s member functions are able to access class’s data
fields having public or private accessibility for all times. However, externally created object(s)
can only access public data members of that class and private data members are restricted to be
accessed outside the class. For example, consider the following class:
class Examp
{
private:
int attribute;
public:
void show()
{
cout<<attribute;
}
};
Any externally created instance (e.g. Obj) of class Examp would not be able to access data
member(s) directly while using the dot (.) operator. Hence, in the main() function, the statement
Obj.attribute is not legal but the statement Obj.show() is legal.
It is sufficient to know about public and private access specifiers/modifiers in the absence of
inheritance. However, in case of inheritance, sometimes it is required to access data member(s)
of base class in derived class(es) but not outside these classes. In this situation, you must make
access protected for that data member(s) rather than private or public. Protected access will
ensure access of data members only within inheritance hierarchy.
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.
Public Inheritance:
Syntax: class Student: public Person { };
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.
Protected Inheritance:
Syntax: class Student: protected Person { };
2
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.
Private Inheritance:
Syntax: class Student: private Person { };
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.
3. Concept Map
Inheritance is one of the most important building blocks of OOP. The concept of reusable classes
is helpful to manage objects. You can create new classes (derived classes) that are able to inherit
certain attributes and behavior of their ancestor or base class(es). Prior to working with
inheritance, it was important to consider that data member(s) should have private access and
only through public member functions, you can access data members of a class. However, with
inheritance, it is sometimes required to have an intermediate level of accessibility to class’s data
member(s) that exists only within inheritance class hierarchy but not outside these classes.
C++ provides intermediate level of accessibility through protected access specifier. Data
member(s) of a base class with protected accessibility are only be directly accessible within base
class and all of its derived classes but not in other parts of the program. Nevertheless, you should
be careful while making data field(s) protected. Use protected access only where you think that
derived classes will use base class data field(s). The access of protected data members in the
derived classes make them less secure than private data members.
Moreover, access specifiers also play their role in the inheritance process. Considering access
specification in C++, inheritance can be private, protected, or public. The effects of access
specifiers in inheritance process on derived class’s member(s) are different as illustrated in Table
2.
Table 2: Inheritance access specifiers and their effect on derived class members
3
LAB TASKS:
TASK 1:
From the Rectangle class, derive a class named Cuboid that contains
a data field named height in addition to length and width,
two functions named setHeight and getHeight() to set and get value of height data field,
and
a member function named cuboidArea() to calculate the area of a cuboid (length x width
x height)
Draw UML diagram for each class and show inheritance relationship between these classes.
#include <iostream>
using namespace std;
public:
// Mutator functions
4
void setLength(int l) {
length = l;
}
void setWidth(int w) {
width = w;
}
// Accessor functions
int getLength() {
return length;
}
int getWidth() {
return width;
}
public:
// Mutator for height
void setHeight(int h) {
height = h;
}
5
int main() {
Rectangle rect;
rect.setLength(10);
rect.setWidth(5);
cout << "Rectangle Area: " << rect.recArea() << endl;
Cuboid cub;
cub.setLength(10);
cub.setWidth(5);
cub.setHeight(3);
cout << "Cuboid Area (Volume): " << cub.cuboidArea() << endl;
return 0;
}
Task-2
6
o courseName (e.g. OOP),
o creditHours (e.g. 3 or 4), and
o courseFee (e.g. Rs. 10,000).
A parameterized constructor to initialize data members with values specified by the user
Implement both classes and in the main() function, create an instance of ResearchCourse class.
Invoke appropriate functions to display all attribute values as well as the total fee for this
particular instance.
Task 3
7
Write a main() function that instantiates objects of Convertible class and test the functionality of
all its member functions.
#include <iostream>
using namespace std;
public:
// Parameterized constructor
GraduateCourse(string id, string name, int credits, int fee) {
courseID = id;
courseName = name;
creditHours = credits;
courseFee = fee;
}
};
public:
// Parameterized constructor for derived class
ResearchCourse(string id, string name, int credits, int fee, int expFee)
: GraduateCourse(id, name, credits, fee) {
experimentFee = expFee;
}
// Display function
void display() {
cout << "Course ID: " << courseID << endl;
cout << "Course Name: " << courseName << endl;
cout << "Credit Hours: " << creditHours << endl;
8
cout << "Course Fee: Rs. " << courseFee << endl;
cout << "Experiment Fee: Rs. " << experimentFee << endl;
}
int main() {
// Create a ResearchCourse object
ResearchCourse course("CS2133", "OOP", 3, 10000, 2000);
return 0;
}
9
Task 4
Derive a class named StaffService from the class CafeService that holds the following:
Two data members i.e.
o serviceFee,
o the cabinNumber to which the service has been made
A function named totalCharges that returns total cost of an order (including serviceFee +
price of food item(s) served)
A parameterized constructor, which requires arguments for all of its own data fields as
well as for the data fields of base class
A member function named display() to show all the details of an order including
orderID, price, and totalCharges
In the main() function, instantiate an object of class StaffService object and test the
implementation of both classes through this object.
10
#include <iostream>
using namespace std;
// Base Class
class CafeService {
protected:
string orderID;
float price;
public:
// No-argument constructor
CafeService() {
orderID = "ord#0";
price = 0.0;
}
// Parameterized constructor
CafeService(string id, float p) {
orderID = id;
price = p;
}
};
// Derived Class
class StaffService : public CafeService {
private:
float serviceFee;
int cabinNumber;
public:
// Parameterized constructor
StaffService(string id, float p, float fee, int cabin)
: CafeService(id, p) {
serviceFee = fee;
cabinNumber = cabin;
}
// Display function
void display() {
cout << "Order ID: " << orderID << endl;
11
cout << "Price of Food: Rs. " << price << endl;
cout << "Service Fee: Rs. " << serviceFee << endl;
cout << "Cabin Number: " << cabinNumber << endl;
cout << "Total Charges: Rs. " << totalCharges() << endl;
}
};
int main() {
// Creating a StaffService object
StaffService order1("ord#101", 850.0, 150.0, 5);
// Displaying details
cout << "--- Order Summary ---" << endl;
order1.display();
return 0;
}
12