CSE Lab Report 2
CSE Lab Report 2
: 02
Experiment Name: Introduction to Object Oriented Programming with Encapsulation,
Inheritance and Polymorphism.
Objectives
Understanding Key OOP Concepts
Hands-on Practice with Classes and Objects
Exploring Polymorphism
Introduction
Class: A class is a blueprint or template for creating objects. It defines attributes (variables)
and methods (functions) that the objects created from the class will have.
Object: An object is an instance of a class. It is a concrete entity that has attributes and
behaviors as defined by its class.
Getter and Setter Methods: Getter methods retrieve the value of private attributes, and
setter methods allow controlled modification of these attributes.
Encapsulation: Encapsulation is the process of bundling the data (attributes) and methods
(functions) that operate on the data into a single unit, typically a class. It restricts direct
access to some of the object's components, which is achieved by using access modifiers (like
private, protected, and public). Access to these components is controlled through getter and
setter methods.
Inheritance: Inheritance is a mechanism by which one class (child or subclass) can acquire
the properties and methods of another class (parent or superclass). It allows for code reuse
and the creation of hierarchical relationships between classes.
Polymorphism: Polymorphism allows methods in different classes to have the same name
but behave differently based on the object's type. It can be achieved through method
overriding (runtime polymorphism) or method overloading (compile-time polymorphism,
supported differently in various languages).
Method Overriding: Method overriding allows a child class to provide its specific
implementation of a method that is already defined in its parent class.
Method Overloading; Method overloading allows multiple methods in the same class to
have the same name but with different parameters. This is implemented differently across
programming languages (Python uses default arguments).
Codes
Encapsulation
# include <iostream>
using namespace std;
1|Page
class Result
{
private :
float cgpa;
public :
void setName(float x)
{
cgpa = x;
}
float getName()
{
return cgpa;
}
};
int main()
{
Result r1;
r1.setName (3.79);
cout << r1.getName();
}
Explanation:
1. Class (Result):
This class represents a blueprint for handling a cgpa value using
encapsulation.
Private Attribute (cgpa):
cgpa is declared as private, meaning it cannot be accessed or modified
directly from outside the class.
Public Methods:
setName(float x): This is a setter method that allows you to assign a
value to cgpa.
getName(): This is a getter method that retrieves the current value of
cgpa.
2. Encapsulation
The private access modifier ensures that the cgpa attribute is hidden from
external access.
The public methods (setName and getName) act as controlled interfaces to
access and modify cgpa.
3. Main Fuction
Result r1; : Creates an object r1 of the class Result.
r1.setName(3.79); : Calls the setName method to assign the value 3.79 to the
private attribute cgpa of the object r1.
2|Page
cout << r1.getName(); : Calls the getName method to retrieve the value of
cgpa and prints it to the console.
Output
Inheritance
#include <iostream>
#include <string>
using namespace
std;
class Person {
public:
string name;
int id;
void introduce() {
cout << "Hi, I am " << name << " and my student ID is
" << id << endl;
}
};
int main()
{
Student student;
student.name = "Rakib";
student.id = 2208017;
3|Page
student.introduce();
student.dept();
return 0;
}
Explanation:
1. Person Class:
This is the base class that contains attributes and a method that can be used
by its objects or by derived classes.
Attributes:
name: A public string to store the name of a person.
id: A public int to store the ID of a person.
Method:
introduce(): A public method that prints a message introducing the person
by their name and ID.
2. Student Class:
This is the derived class that inherits from the Person class using public
inheritance.
Inheritance:
Since Student inherits publicly from Person, all public members of Person
(like name, id, and introduce) are directly accessible in the Student class
and its objects.
Additional Method:
dept(): A method specific to the Student class, which prints the student's
name along with their department.
3. main() Function:
The entry point of the program where the classes are utilized.
Steps:
Create an object student of the Student class.
Assign values to student.name and student.id. Since Student inherits from
Person, the name and id attributes are accessible.
Call student.introduce(): This method is inherited from the Person class
and prints the student's name and ID.
Call student.dept(): This method belongs to the Student class and prints a
message about the student's department.
Return 0 to indicate successful execution.
4|Page
Output
Polymorphism
#include <iostream>
using namespace std;
class Shape {
public:
double dim1, dim2;
// Constructor
Shape(double dim1, double dim2) : dim1(dim1), dim2(dim2)
{}
// Virtual destructor
virtual ~Shape() {}
5|Page
// Override area function
double area() const override {
return dim1 * dim2;
}
};
int main() {
// Polymorphism with base class pointer
Shape* p;
// Pointing to Triangle
p = &t;
cout << "Triangle area = " << p->area() << endl;
// Pointing to Rectangle
p = &r;
cout << "Rectangle area = " << p->area() << endl;
return 0;
}
Explanation
1. Base Class: Shape
Purpose: Represents a generic shape with dimensions dim1 and dim2.
Constructor:
Shape(double dim1, double dim2): Initializes dim1 and dim2.
Destructor:
Declared as virtual to ensure proper cleanup of derived class
objects when deleted through a base class pointer.
Virtual Function:
virtual double area() const: A virtual function that computes the
area. It is meant to be overridden in derived classes. The base
implementation returns 0, as the base class does not represent a
specific shape.
2. Derived Class: Triangle
Purpose: Represents a triangle and calculates its area using the formula:
1
Area = × dim1 × dim2
2
Constructor:
6|Page
Triangle(double dim1, double dim2): Uses the base class
constructor to initialize dimensions.
Overridden Function:
Overrides the area() function to calculate the triangle's area.
3. Derived Class: Rectangle
Purpose: Represents a rectangle and calculates its area using the formula:
Area=dim1×dim2
Constructor:
Rectangle(double dim1, double dim2): Uses the base class
constructor to initialize dimensions.
Overridden Function:
Overrides the area() function to calculate the rectangle's area.
4. main() Function
Demonstrates polymorphism by using a pointer of the base class (Shape*)
to point to derived class objects.
Create Triangle and Rectangle objects.
Assign the address of the Triangle object to the base class pointer p, and
call the area() function.
Assign the address of the Rectangle object to p, and call the area()
function.
The appropriate area() function (from the Triangle or Rectangle class) is
executed because of runtime polymorphism enabled by the virtual
keyword.
Output
7|Page
pointer (Shape*), the program dynamically binds to the appropriate area() function of the
actual object being pointed to, whether it is a Triangle or Rectangle. This eliminates the need
for conditional statements to determine the type of shape, enhancing both code readability
and maintainability.
The inclusion of a virtual destructor in the base class ensures proper cleanup of resources
when objects are deleted through base class pointers. Although this example does not involve
dynamic memory allocation, the practice illustrates robust programming principles for
handling real-world scenarios.
The program's structure is inherently scalable. Adding new shapes, such as circles or
trapezoids, requires creating new derived classes and overriding the area() method without
modifying the existing code. This demonstrates the flexibility and extensibility of the design.
In conclusion, the program effectively demonstrates the power of object-oriented
programming in C++. By combining encapsulation, inheritance, and polymorphism, it
provides a reusable and maintainable solution for calculating areas of various shapes. The use
of dynamic binding ensures that the correct behavior is executed at runtime, while the
modularity of the design makes it adaptable for future extensions. This approach is not only
efficient but also well-suited for real-world applications requiring dynamic and hierarchical
relationships between objects.
8|Page