Unit 5 · 10 teaching hours · 37 min read
Object-Oriented Programming (OOP)
What the syllabus asks for 4
- Programming paradigms: procedural, structural and object oriented
- Features of OOP: Class, Object, Polymorphism and Inheritance
- Advantages of OOP
- Application of OOP
Every program you wrote in Unit 4 was a list of instructions that pushed data
around: main() called a function, the function worked on variables, and the
variables sat outside in the open.
Object-oriented programming turns that picture inside out. Data and the code that is allowed to touch it are locked together into one unit called an object, and a program becomes a set of objects sending messages to each other.
This unit is about that idea — the four features the syllabus names (class, object, inheritance, polymorphism), why the software industry moved to it, and where it is used.
This is a 10-hour unit but it is mostly theory. Group B almost always has one of: define class and object with an example, differentiate between procedural and object-oriented programming, explain any four features of OOP.
Group C asks you to write a program with a class, a constructor, inheritance and function overloading/overriding, so learn one complete program template by heart. All example code here is C++, the language NEB uses for OOP.
5.1 Programming paradigms: procedural, structural and object oriented
A programming paradigm is a style of organising a program — a way of thinking about what a program is. Three paradigms matter for this course.
Procedural (or monolithic-then-procedural) programming. The program is a sequence of instructions grouped into procedures (functions). Data is usually global, so any function can read or change it.
Design is top-down: split the job into functions, then split those into smaller functions. FORTRAN (1957), COBOL (1959) and C (1972) are procedural languages.
Structured programming. This is procedural programming with discipline added.
It insists that every algorithm be built from only three control
structures — sequence, selection (if, switch) and iteration (for, while)
— each with a single entry and a single exit, and that goto be avoided.
Dijkstra's 1968 letter "Go To Statement Considered Harmful" started it. A structured program is divided into independent modules that communicate through parameters and return values instead of global variables.
C is the classic structured language, and everything you did in Unit 4 was structured programming.
Object-oriented programming. The program is organised around the data, not the actions.
Data and the functions that operate on it are wrapped into a single unit (an object); outside code can only reach the data through the functions the object chooses to publish.
Design is bottom-up: first identify the objects in the problem, then give them behaviour.
Simula 67 (Dahl and Nygaard, 1967) was the first object-oriented language; Smalltalk (Xerox PARC, 1970s) made the ideas famous; C++ (Bjarne Stroustrup, Bell Labs — "C with Classes" in 1979, renamed C++ in 1983, released 1985), Java (1995), Python, C# and Kotlin are the languages in use today.
The same tiny job — the area of a rectangle — written both ways makes the difference concrete. First procedural C:
#include <stdio.h>
struct Rect { float len, bre; }; /* data only */
float area(struct Rect r) { /* function kept separate */
return r.len * r.bre;
}
int main() {
struct Rect r = {12.5f, 8.0f};
printf("Area = %.2f sq. m\n", area(r));
return 0;
}
Output:
Area = 100.00 sq. m
Nothing stops another part of the program from writing r.len = -5;. Now the
object-oriented version in C++:
#include <iostream>
using namespace std;
class Rect {
float len, bre; // data: private, hidden
public:
Rect(float l, float b) { // constructor
len = l; bre = b;
}
float area() { // behaviour: bundled with the data
return len * bre;
}
};
int main() {
Rect r(12.5, 8.0);
cout << "Area = " << r.area() << " sq. m" << endl;
return 0;
}
Output:
Area = 100 sq. m
r.len is now inaccessible from main(); the only way in is the constructor,
and the only way out is area().
| Feature | Procedural / structured | Object-oriented |
|---|---|---|
| Basic unit | function (procedure) | class / object |
| Design direction | top-down | bottom-up |
| Data handling | mostly global, shared | private inside objects |
| Data security | weak — any function can change data | strong — access specifiers protect data |
| Code reuse | by calling functions again | by inheritance, plus functions |
| Adding a new feature | often means editing existing functions | usually means adding a new class |
| Real-world modelling | poor | direct (one object per real thing) |
| Suitable for | small and medium programs | large, long-lived, multi-programmer software |
| Examples | C, FORTRAN, COBOL, Pascal | C++, Java, Python, C#, Kotlin |
The syllabus word structural means structured programming, which is a disciplined form of procedural programming — not a separate family. C is both procedural and structured. Do not write that C is "structural but not procedural".
5.2 Features of OOP: class, object, polymorphism and inheritance
5.2.1 Class and object
A class is a user-defined data type that binds together data members (attributes) and member functions (methods) under one name. It is only a blueprint — writing a class allocates no memory for data.
An object is an instance of a class: a real variable of that class type, with its own copy of the data members, created in memory at run time.
Class is to object what struct Student is to a particular student variable —
except that a class also carries the functions. In Rect r(12.5, 8.0); the class
is Rect and the object is r.
The general form of a class in C++ is:
class ClassName {
private: // default; hidden from outside
// data members
protected: // visible to derived classes only
// data members
public: // the interface
ClassName(); // constructor
~ClassName(); // destructor
// member functions
}; // note the semicolon
A constructor is a member function with the same name as the class, with no return type, called automatically when an object is created; it is used to initialise the data members.
A destructor (~ClassName()) is called
automatically when the object is destroyed. Here is a full class with both kinds
of constructor, a validating setter and a static member:
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
class Student {
// ---- private data members: hidden state of the object ----
string name;
int roll;
int marks[3];
public:
static int count; // one copy shared by all objects
Student() { // default constructor
name = "not admitted"; roll = 0;
marks[0] = marks[1] = marks[2] = 0;
count++;
}
Student(string n, int r, int m1, int m2, int m3) { // parameterised
name = n; roll = r;
marks[0] = m1; marks[1] = m2; marks[2] = m3;
count++;
}
int total() const { return marks[0] + marks[1] + marks[2]; }
double percentage() const { return total() / 3.0; }
char grade() const {
double p = percentage();
if (p >= 80) return 'A';
else if (p >= 60) return 'B';
else if (p >= 40) return 'C';
else return 'F';
}
void setMarks(int i, int m) { // controlled write access
if (i >= 0 && i < 3 && m >= 0 && m <= 100) marks[i] = m;
else cout << "Invalid mark rejected" << endl;
}
void display() const {
cout << setw(5) << roll << setw(16) << name << setw(7) << total()
<< setw(9) << fixed << setprecision(2) << percentage()
<< setw(7) << grade() << endl;
}
};
int Student::count = 0; // static member defined outside
int main() {
Student s1("Sita Rai", 1, 78, 85, 92);
Student s2("Bikash Thapa", 2, 55, 61, 48);
cout << setw(5) << "Roll" << setw(16) << "Name" << setw(7) << "Total"
<< setw(9) << "Percent" << setw(7) << "Grade" << endl;
s1.display();
s2.display();
s2.setMarks(1, 105); // rejected by the setter
cout << "Students created = " << Student::count << endl;
return 0;
}
Output (compiled with g++ student.cpp -o student):
Roll Name Total Percent Grade
1 Sita Rai 255 85.00 A
2 Bikash Thapa 164 54.67 C
Invalid mark rejected
Students created = 2
5.2.2 Data encapsulation and data hiding
Encapsulation is the wrapping of data and the functions that act on it into one unit — the class.
The consequence is data hiding: because name, roll
and marks are private, no statement outside the class can read or write them
directly. s1.marks[0] = 999; is a compile-time error.
All traffic goes through
the public interface, which can check it — that is why setMarks(1, 105)
printed a rejection instead of storing an impossible mark.
| Access specifier | Same class | Derived class | Outside the class |
|---|---|---|---|
private |
yes | no | no |
protected |
yes | yes | no |
public |
yes | yes | yes |
5.2.3 Abstraction
Abstraction means showing only the essential features and hiding the
internal detail. You call s1.percentage() without knowing whether the marks
are stored in an array, three separate variables or a file.
In C++, abstraction
is achieved with the class interface and, at a higher level, with abstract
classes — classes containing at least one pure virtual function
(virtual double earning() const = 0;), which cannot be instantiated and exist
only to fix the interface that derived classes must provide.
Encapsulation is how it is hidden (bundling + access specifiers); abstraction is what the user is shown (the interface). Give this one line and one example in the exam and the mark is yours.
5.2.4 Inheritance
Inheritance is the mechanism by which one class (the derived, child or sub-class) acquires the data members and member functions of another class (the base, parent or super-class), and may then add its own members or redefine inherited ones.
It gives reusability and expresses an "is-a" relationship: a Teacher is a Person.
class Teacher : public Person { // public inheritance
// extra members
};
Five forms of inheritance are examinable:
| Type | Structure | Example |
|---|---|---|
| Single | one base, one derived | Person → Student |
| Multilevel | derived class becomes a base | Person → Student → HostelStudent |
| Multiple | one derived, two or more bases | Student + Athlete → SportsScholar |
| Hierarchical | one base, many derived | Person → Student, Teacher, Staff |
| Hybrid | a combination of the above | multilevel + multiple together |
When an object of a derived class is created, the base constructor runs first, then the derived constructor; destructors run in the exact reverse order. This order is a favourite one-mark question.
5.2.5 Polymorphism
Polymorphism (Greek: many forms) is the ability of one name, operator or message to behave differently depending on the type or number of the data it is used with.
C++ provides compile-time polymorphism through function overloading and operator overloading, and run-time polymorphism through virtual functions and overriding.
Compile-time (static) polymorphism. Several functions share one name but differ in the number or type of parameters; the compiler picks the right one from the call:
#include <iostream>
using namespace std;
// compile-time polymorphism: one name, three different signatures
int volume(int s) { return s * s * s; } // cube
int volume(int l, int b, int h) { return l * b * h; } // cuboid
double volume(double r, double h) { return 3.1416 * r * r * h; } // cylinder
int main() {
cout << "Cube : " << volume(4) << endl;
cout << "Cuboid : " << volume(5, 4, 3) << endl;
cout << "Cylinder : " << volume(2.0, 7.0) << endl;
return 0;
}
Output:
Cube : 64
Cuboid : 60
Cylinder : 87.9648
Run-time (dynamic) polymorphism. A base-class pointer holds a derived-class object, and the function that actually runs is decided while the program is running.
The base function must be declared virtual, otherwise the compiler
binds the call early and the base version runs:
#include <iostream>
using namespace std;
class Base {
public:
void show() { cout << "Base::show (not virtual)" << endl; }
virtual void draw() { cout << "Base::draw (virtual)" << endl; }
};
class Derived : public Base {
public:
void show() { cout << "Derived::show" << endl; }
void draw() override { cout << "Derived::draw" << endl; }
};
int main() {
Derived d;
Base *bp = &d; // base pointer holding a derived object
bp->show(); // early (compile-time) binding -> Base
bp->draw(); // late (run-time) binding -> Derived
return 0;
}
Output:
Base::show (not virtual)
Derived::draw
| Function overloading | Function overriding | |
|---|---|---|
| Where | same class (or scope) | base class and derived class |
| Signature | must differ | must be identical |
| Binding | early, at compile time | late, at run time |
| Keyword needed | none | virtual in the base class |
| Type of polymorphism | compile-time (static) | run-time (dynamic) |
5.2.6 Message passing and dynamic binding
Objects do not call each other's code directly; they send messages — a
message is the name of a member function plus its arguments, sent to a named
object (s1.display()).
Dynamic binding (late binding) means the code
associated with a message is not known until run time, which is exactly what
makes p[i]->display() behave differently for each element of the array below.
Putting every feature into one program gives the classic Group C answer:
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
// ---------------- base class ----------------
class Person {
protected:
string name;
int age;
public:
Person(string n, int a) : name(n), age(a) {
cout << "Person constructor: " << name << endl;
}
virtual void display() const { // virtual -> late binding
cout << left << setw(14) << name << setw(5) << age;
}
virtual double earning() const = 0; // pure virtual: abstract class
virtual ~Person() { cout << "Person destructor: " << name << endl; }
};
// ---------------- derived class 1 ----------------
class Teacher : public Person {
string subject;
double salary;
public:
Teacher(string n, int a, string s, double sal)
: Person(n, a), subject(s), salary(sal) {
cout << "Teacher constructor: " << name << endl;
}
void display() const override {
Person::display(); // reuse the base version
cout << setw(10) << "Teacher" << setw(12) << subject
<< "Rs " << fixed << setprecision(2) << earning() << endl;
}
double earning() const override { return salary; }
};
// ---------------- derived class 2 ----------------
class Student : public Person {
string faculty;
double scholarship;
public:
Student(string n, int a, string f, double sc)
: Person(n, a), faculty(f), scholarship(sc) {
cout << "Student constructor: " << name << endl;
}
void display() const override {
Person::display();
cout << setw(10) << "Student" << setw(12) << faculty
<< "Rs " << fixed << setprecision(2) << earning() << endl;
}
double earning() const override { return scholarship; }
};
int main() {
Person *p[3]; // base-class pointers
p[0] = new Teacher("Ram Sharma", 41, "Computer", 48500);
p[1] = new Student("Sita Rai", 18, "Science", 1200);
p[2] = new Teacher("Gita Magar", 35, "Maths", 52000);
cout << "\n--- Staff and student list ---" << endl;
double sum = 0;
for (int i = 0; i < 3; i++) {
p[i]->display(); // same call, different code
sum += p[i]->earning();
}
cout << "Total monthly payout = Rs " << sum << "\n" << endl;
for (int i = 0; i < 3; i++) delete p[i]; // virtual destructor runs
return 0;
}
Output:
Person constructor: Ram Sharma
Teacher constructor: Ram Sharma
Person constructor: Sita Rai
Student constructor: Sita Rai
Person constructor: Gita Magar
Teacher constructor: Gita Magar
--- Staff and student list ---
Ram Sharma 41 Teacher Computer Rs 48500.00
Sita Rai 18 Student Science Rs 1200.00
Gita Magar 35 Teacher Maths Rs 52000.00
Total monthly payout = Rs 101700.00
Person destructor: Ram Sharma
Person destructor: Sita Rai
Person destructor: Gita Magar
A class diagram is how this design is drawn on paper. UML notation puts the
class name, then attributes, then methods in one box, marks private members with
- and public with +, uses a hollow triangle arrow for inheritance and a plain
line for association.
| OOP principle | What it means | Example from this chapter |
|---|---|---|
| Class | blueprint of data + methods | class Student { ... }; |
| Object | an instance with its own data | Student s1("Sita Rai", 1, 78, 85, 92); |
| Encapsulation | data + methods in one unit | marks[3] is private, reached via setMarks() |
| Data hiding | outsiders cannot touch the data | s1.marks[0] = 999; fails to compile |
| Abstraction | show the interface, hide the detail | percentage() hides how marks are stored |
| Inheritance | derived class reuses a base class | class Teacher : public Person |
| Polymorphism | one name, many behaviours | volume() overloaded; earning() overridden |
| Dynamic binding | function chosen at run time | p[i]->display() inside the loop |
| Message passing | calling a method on an object | s1.display() |
Problem. Write a C++ class Employee with a parameterised constructor that
stores a name and a basic salary. Add member functions to compute a 20 % allowance,
the gross pay, 1 % social-security tax on the gross, and the net pay.
Show the payslip for Hari Bahadur, whose basic salary is Rs 35,000.
Solution.
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
class Employee {
string name;
double basic;
public:
Employee(string n, double b) : name(n), basic(b) {}
double allowance() const { return 0.20 * basic; } // 20% of basic
double gross() const { return basic + allowance(); }
double tax() const { return 0.01 * gross(); } // 1% social security
double net() const { return gross() - tax(); }
void payslip() const {
cout << "Employee : " << name << endl;
cout << fixed << setprecision(2);
cout << " Basic Rs " << setw(10) << basic << endl;
cout << " Allowance Rs " << setw(10) << allowance() << endl;
cout << " Gross Rs " << setw(10) << gross() << endl;
cout << " Tax (1%) Rs " << setw(10) << tax() << endl;
cout << " Net pay Rs " << setw(10) << net() << endl;
}
};
int main() {
Employee e("Hari Bahadur", 35000);
e.payslip();
return 0;
}
Checking the arithmetic by hand: allowance = 0.20 \times 35000 = 7000, gross = 35000 + 7000 = 42000, tax = 0.01 \times 42000 = 420, net = 42000 - 420 = 41580. The program prints exactly that:
Employee : Hari Bahadur
Basic Rs 35000.00
Allowance Rs 7000.00
Gross Rs 42000.00
Tax (1%) Rs 420.00
Net pay Rs 41580.00
Problem. What does this program print, and why?
class A {
public:
A() { cout << "A "; }
void f() { cout << "A::f "; }
virtual void g() { cout << "A::g "; }
};
class B : public A {
public:
B() { cout << "B "; }
void f() { cout << "B::f "; }
void g() { cout << "B::g "; }
};
int main() { A *p = new B(); p->f(); p->g(); }
Solution. new B() first runs the base constructor A(), then B(), so the
first output is A B. f() is not virtual, so p->f() is bound at compile
time using the pointer's type A* and prints A::f. g() is virtual, so
the call is bound at run time using the object's real type B and prints B::g.
Full output: A B A::f B::g
- Forgetting the semicolon after the closing brace of a class.
- Writing a return type for a constructor (
void Student()is not a constructor). - Expecting a base pointer to call the derived function without
virtual— it will not. Overriding needsvirtualin the base class.
5.3 Advantages of OOP
Eight advantages, each explained in full.
1. Reusability. Through inheritance a tested class can be extended instead of
rewritten, and a class can be packed into a library for others to use. A Person
class written once can serve Student, Teacher and Staff. This saves time and
reduces new errors.
2. Data security. Access specifiers make the data private, so unrelated code
cannot corrupt it. A bank account class can allow the balance to change only through
deposit() and withdraw(). Data hiding therefore protects the object from misuse.
3. Easier maintenance. A bug in percentage() can only be caused by code inside
Student, so the search is limited to one class, not the whole program. Each class
can be corrected or improved without touching the others. Large programs remain
manageable over many years.
4. Modelling power. Objects map one-to-one onto real things such as a student, an invoice or a bus route. The design is therefore natural and easy to discuss with the customer. Analysis, design and coding use the same ideas.
5. Extensibility. A new class can be added without changing existing code. Adding a
Staff class to the payroll program needs no change in main(), because main()
talks only to Person*. The program grows by addition, not by modification.
6. Modular team work. Different programmers can own different classes and agree only on the public interfaces. A team of five can build five classes in parallel and join them at the end. This speeds up big projects.
7. Polymorphism and flexibility. One function name or one message can do different
jobs for different objects. A loop that calls area() for every shape works for all
the shapes, even those added later. The code becomes shorter and clearer.
8. Message passing. Objects communicate by sending messages, that is, by calling member functions. This makes the communication of a large system explicit and easy to trace. Each object remains independent of how others work inside.
The costs are real too, and examiners accept them as "disadvantages": programs are larger and need more memory, execution can be slightly slower because of dynamic binding, the design phase takes longer, and the paradigm is overkill for a 20-line calculation.
5.4 Application of OOP
| Application area | Why OOP fits | Typical tools |
|---|---|---|
| Graphical user interfaces | every widget is an object with properties and events | Qt, Android SDK, JavaFX |
| Simulation and modelling | the original purpose of Simula — each entity is an object | traffic, weather, queue simulations |
| Computer games and graphics | player, enemy, bullet all inherit from a common base | Unity (C#), Unreal (C++) |
| Mobile applications | activity/view classes are extended by the developer | Kotlin, Swift |
| Web frameworks | request, model, controller classes | Laravel (PHP), Django (Python) |
| Operating systems and device drivers | device classes with a common interface | C++ subsystems in Windows, macOS |
| CAD/CAM and design software | geometric shapes form a natural class hierarchy | AutoCAD, SolidWorks |
| Database and ORM layers | a table row becomes an object | Hibernate, Eloquent |
| Banking, ERP and payroll software | account, customer, transaction objects; auditability | Java/C# enterprise systems |
| AI and data-science libraries | model classes with a shared fit/predict interface |
scikit-learn, TensorFlow |
Eight applications explained.
1. Graphical user interfaces. Every window, button and text box is an object with properties (colour, size) and events (click). Frameworks such as Qt and the Android SDK are built from such classes. A programmer builds a new screen by extending them.
2. Simulation and modelling. The first object-oriented language, Simula, was made to simulate real systems. Each vehicle, patient or customer in a queue is an object with its own state. Traffic and bank-queue simulations are typical.
3. Computer games. Player, enemy and bullet inherit from one base class and are drawn and moved by the same loop. Engines such as Unity and Unreal use this design. New characters are added by creating new classes.
4. Mobile applications. Apps for Android (Kotlin or Java) and iPhone (Swift) are written by extending activity and view classes. Wallet and ticketing apps used in Nepal are built this way.
5. Web frameworks. Frameworks such as Laravel and Django model requests, data and controllers as classes. A college website can add a new page type by adding a new class.
6. Operating systems and device drivers. Devices such as printers and disks are objects that share a common interface. The system treats all of them in the same way, whatever the hardware.
7. CAD and design software. Lines, circles and other shapes form a natural class hierarchy, and each knows how to draw and measure itself. Programs such as AutoCAD work like this.
8. Banking, ERP and payroll software. Account, customer and transaction are objects with clear rules and an audit trail. Enterprise systems in banks are normally written in Java or C#. The same design supports AI libraries and database layers.
Problem. A Kathmandu school wants(a) a program to convert a temperature from Celsius to Fahrenheit for a physics class, and(b) a school management system holding students, teachers, fees, attendance and exam results, to be maintained for the next ten years by different programmers. Which paradigm suits each, and why?
Solution. (a) Procedural/structured C is the right choice. The task is a single formula, F = \frac{9}{5}C + 32; one function is enough, and a class would add code without adding safety.
(b) Object-oriented design is the right choice.
There are many real-world
entities (Student, Teacher, Fee, Attendance, Exam) with shared attributes, so a
Person base class removes duplication; the data is sensitive, so private
members with validating setters protect it; the system will be extended for ten
years, so adding a class must not break existing code; and several programmers
can own separate classes at once.

Chapter summary
- A paradigm is a style of organising a program: procedural (functions on shared data), structured (procedural with only sequence/selection/iteration and modules), object-oriented (data and behaviour bundled into objects).
- A class is a blueprint binding data members and member functions; an object is an instance of a class with its own copy of the data.
- A constructor has the class's name, no return type, and runs automatically
at creation; the destructor
~Class()runs at destruction. In inheritance, constructors run base→derived and destructors derived→base. - Encapsulation bundles data with methods; data hiding follows from
private; abstraction exposes only the interface.private= class only,protected= class + derived,public= everywhere. - Inheritance (single, multilevel, multiple, hierarchical, hybrid) gives
reuse and expresses "is-a"; the derived class inherits with
class D : public B. - Polymorphism is compile-time (function/operator overloading, early
binding) or run-time (overriding a
virtualfunction through a base pointer, late binding). - Advantages: reusability, data security, easy maintenance, real-world modelling, extensibility, parallel team work. Costs: bigger code, slower dynamic dispatch, longer design phase.
- OOP is used for GUIs, simulation, games, mobile apps, web frameworks, operating systems, CAD, ORMs, banking systems and ML libraries.
Practice questions
Group A — Multiple choice (1 mark each)
- Which of the following is not a feature of object-oriented programming? [1]ainheritancebpolymorphismcencapsulationdglobal data sharing
- A class is best described as [1]aan instance of an objectba blueprint for objectsca block of memoryda library function
- Which member function is called automatically when an object is created? [1]adestructorbfriend functioncconstructord
main() - Members declared
protectedin a base class are accessible in [1]athe base class onlybthe base and derived classesceverywherednowhere - Function overloading is an example of [1]arun-time polymorphismbcompile-time polymorphismcinheritancedencapsulation
class C : public A, public Bis an example of [1]asingle inheritancebmultilevel inheritancecmultiple inheritancedhierarchical inheritance
Answers to Group A
1. (d) — OOP hides data rather than sharing it globally.
2. (b) — a class allocates no data memory; objects do.
3. (c) — the constructor; it has the class name and no return type.
4. (b) — protected is private to the outside world but visible to children.
5. (b) — the compiler picks the version from the signature.
6. (c) — one derived class with two base classes.
Group B — Short answer (5 marks each)
- Define class and object. Write a C++ class
Circlewith a constructor and a member function that returns the area, and create one object of it. [5] - Differentiate between procedural and object-oriented programming on any five points. [5]
- What is inheritance? Explain any three types with a diagram. [5]
- Distinguish between function overloading and function overriding with one example of each. [5]
- State any five advantages of OOP and any two of its disadvantages. [5]
Answers to Group B
1. Definitions as in §5.2.1. Program:
#include <iostream>
using namespace std;
class Circle {
double r;
public:
Circle(double radius) { r = radius; }
double area() { return 3.1416 * r * r; }
};
int main() {
Circle c(7.0);
cout << "Area = " << c.area() << endl; // prints Area = 153.938
return 0;
}
Check: 3.1416 \times 7^2 = 3.1416 \times 49 = 153.9384, so the output is
Area = 153.938 (cout shows six significant figures by default).
2.
| Point | Procedural programming | Object-oriented programming |
|---|---|---|
| Basic unit | Function (procedure) | Class and object |
| Design direction | Top-down | Bottom-up |
| Data handling | Data are global and shared by functions | Data are hidden inside objects |
| Security | Weak, anyone can change the data | Strong, through access specifiers |
| Reuse | Copy and modify functions | Inheritance and libraries |
| Suitability | Small tasks and calculations | Large, long-lived systems |
| Examples | C, Pascal, FORTRAN | C++, Java, Python |
In procedural programming the program is a list of steps and functions that act on shared data, so a change in a data layout can break many functions.
In object-oriented programming the data and the functions that use them are packed together in a class, so the program is organised around the things it models.
A single formula such as converting Celsius to Fahrenheit needs only a procedure, but a school management system with students, teachers and fees is much better as a set of objects.
3. Inheritance is the property by which a derived class acquires the members of a base class, giving reuse and an "is-a" relationship (a Teacher is a Person).
Three types: (i) Single inheritance: one derived class from one base
class, A → B; a Student derived from Person.
(ii) Multilevel inheritance: a
chain of derivation, A → B → C; Person → Student → GraduateStudent; each level
inherits all members of the levels above it.
(iii) Hierarchical inheritance: one
base class with several derived classes; Person is the base of Student,
Teacher and Staff. Multiple inheritance (A, B → C) lets a class have two bases
and is also available in C++.
In C++ the syntax is class Teacher : public Person.
(Draw the figure of section 5.2.4 with arrows from derived to base.) Inheritance saves coding time, makes programs shorter and lets new classes be added without changing old ones, but a deep hierarchy can become hard to follow.
4. Function overloading means several functions with the same name in the same scope, but with different parameter lists (number or type); the compiler chooses one at compile time (early binding).
Example volume(int a) for a cube and
volume(int l, int b, int h) for a cuboid. Function overriding means a derived
class redefines a function of its base class with the same signature; with the
virtual keyword the call is resolved at run time (late binding).
Example Person::earning() is overridden by Teacher::earning().
| Basis | Overloading | Overriding |
|---|---|---|
| Classes | Same class | Base and derived classes |
| Signature | Different | Identical |
| Binding | Compile time (early) | Run time (late, with virtual) |
| Type of polymorphism | Compile-time | Run-time |
| Purpose | Same job on different data | Specialised behaviour in a derived class |
Overloading makes a program easy to read because one name does related jobs, and overriding lets a base-class pointer call the correct version of a function for each kind of object.
5. Five advantages of OOP: (i) Reusability: inheritance lets tested classes be extended instead of rewritten. (ii) Data security: private data are reachable only through public functions.
(iii) Easier maintenance: a fault is limited to one class. (iv) Real-world modelling: objects match real things, so the design is natural. (v) Extensibility: new classes can be added without changing existing code.
Other advantages are modular teamwork and message passing.
Two disadvantages: (i) programs are larger and need more memory and design time; (ii) execution can be slightly slower because of dynamic binding, and the paradigm is too heavy for very small programs.
For a school management system of many years, the advantages are far greater than the disadvantages.
Group C — Long answer (8 marks each)
- Explain the four features of OOP named in the syllabus — class, object, inheritance and polymorphism — giving a short C++ code fragment for each. [8]
- Write a complete C++ program that defines a base class
Personwithnameandage, derivesTeacher(with subject and salary) andStudent(with faculty and scholarship) from it, uses a virtual function to display the details of each, and prints the total monthly payment for an array of three base-class pointers. [8]
Answers to Group C
1. Definition + fragment for each of the four, as in §5.2: the class/object
fragment from Student, class Teacher : public Person for inheritance, the
overloaded volume() and the virtual earning() for the two kinds of
polymorphism.
One mark for each definition, one for each fragment.
2. The complete program and its verified output are given at the end of §5.2.6.
Marking usually goes: class definitions with correct access specifiers
(2), constructors with an initialisation list or assignment (2), virtual
function correctly overridden (2), array of base pointers and the loop (1),
correct total and output format (1).
The total for the data used is Rs 48,500 + Rs 1,200 + Rs 52,000 = Rs 1,01,700.
Group D — Long answer (10 marks each), with full model answers
- Explain the features of OOP: class, object, encapsulation, abstraction, inheritance and polymorphism. [10]
- Differentiate between procedural and object-oriented programming. Explain the advantages and disadvantages of OOP. [10]
- Define polymorphism. Explain its types with examples and compare overloading with overriding. [10]
Model answer D1: features of OOP (10 marks)
Introduction. Object-oriented programming (OOP) is a programming paradigm in which a program is built from objects that combine data and the functions that act on the data. C++, Java and Python support it. Its main features are as follows.
- Class: a user-defined type or blueprint that describes the data (attributes)
and the functions (methods) common to a group of things.
class Student { ... }; - Object: an instance of a class that occupies memory and has its own values.
Student s1;creates one student object; many objects can be made from one class. - Encapsulation and data hiding: wrapping data and functions in one unit, the
class, and restricting access with
private,protectedandpublic. The balance of an account is private and changes only through public functions. - Abstraction: showing only the essential features and hiding the details. A driver uses the steering wheel and pedals without knowing the engine; a class shows its public interface and hides its code.
- Inheritance: a derived class acquires the members of a base class, giving reuse
and an "is-a" relationship:
class Teacher : public Person. Types are single, multilevel, multiple, hierarchical and hybrid. - Polymorphism: one name, many forms. Compile-time polymorphism uses function and
operator overloading; run-time polymorphism uses
virtualfunctions and overriding. - Message passing and dynamic binding: objects communicate by calling member functions, and the function to execute can be chosen at run time.
class Person { public: virtual double earning() { return 0; } };
class Teacher : public Person { // inheritance
double salary; // data hiding (private by default)
public:
Teacher(double s) { salary = s; }
double earning() { return salary; } // overriding (run-time polymorphism)
};
| Feature | One-line meaning | Keyword in C++ |
|---|---|---|
| Class | Blueprint | class |
| Object | Instance | Student s1; |
| Encapsulation | Data and functions in one unit | private, public |
| Inheritance | Reuse of a base class | : public Base |
| Polymorphism | One name, many forms | virtual, overloading |
Conclusion. These features together make programs secure, reusable and easy to extend, which is why large software in banks and mobile apps is written in an object-oriented way.
Model answer D2: procedural against object-oriented, and the merits (10 marks)
Introduction. A programming paradigm is a style of building programs. In procedural programming (C, Pascal) the program is a sequence of procedures that act on shared data.
In object-oriented programming (C++, Java) the program is a set of objects that hold their own data and behaviour.
| Point | Procedural | Object-oriented |
|---|---|---|
| Basic unit | Function | Class and object |
| Design | Top-down | Bottom-up |
| Data | Global, shared | Hidden inside objects |
| Security | Weak | Strong |
| Reuse | Copy functions | Inheritance |
| Maintenance | Difficult in large programs | Easier, by class |
| Suitable for | Small, simple programs | Large, long-lived systems |
Advantages of OOP. (1) Reusability through inheritance; (2) data security by hiding; (3) easier maintenance; (4) natural modelling of real things; (5) extensibility without changing old code; (6) modular teamwork; (7) polymorphism; (8) message passing.
Disadvantages of OOP. Larger programs and more memory; slightly slower execution because of dynamic binding; longer design time; and it is unnecessary for very small programs.
Example. A Celsius-to-Fahrenheit converter needs only one function and is best written procedurally, whereas a school management system with students, teachers, fees and attendance, to be maintained for ten years by several programmers, is best written with classes.
Conclusion. Neither paradigm is always better; OOP is the right choice when a program is large, changes often and models many real-world things.
Model answer D3: polymorphism (10 marks)
Introduction. Polymorphism means "many forms": the same name or operator behaves in different ways depending on the data or the object it is used with. It is one of the four pillars of OOP.
Types.
- Compile-time (static) polymorphism: the function to call is decided by the
compiler. It is achieved by function overloading (same name, different
parameters) and operator overloading (giving
+a meaning for a user class). Example:volume(int a)for a cube andvolume(int l, int b, int h)for a cuboid. - Run-time (dynamic) polymorphism: the function is chosen while the program runs,
through a base-class pointer and a virtual function. Example: a
Person*that points to aTeachercallsTeacher::earning(), and the same pointer pointing to aStaffcallsStaff::earning().
Person* p[2] = { new Teacher(52000), new Staff(48500) };
for (int i = 0; i < 2; i++) cout << p[i]->earning() << endl; // each object answers in its own way
| Basis | Overloading | Overriding |
|---|---|---|
| Place | Same class | Base and derived class |
| Signature | Different | Same |
| Binding | Early (compile time) | Late (run time), needs virtual |
| Purpose | Same name for related jobs | Special behaviour in a derived class |
Advantages. Shorter and clearer code, easy extension (a new derived class works with old code), and a single interface for many kinds of object.
Conclusion. Polymorphism lets a program treat different objects uniformly while each one behaves correctly, and that is why a payroll loop does not need to change when a new kind of employee is added.
Practise more: Computer Science question bank