When I was learning C++ in my beginning college semesters I faced a lot of confusion in understanding what exactly the concepts of OOPS meant.
I have made a lot of beginner-level mistakes and learned from them. As time passed by, OOPS became my favorite concept in the C++ language.
Here I would slide through some of the important concepts in OOPS.
Before diving into the basics of OOPS, Its important to know what is a Class and an Object.
Class: It is a user-defined datatype that has member functions and different data variables. Memory is allocated to the Class only when an Object is defined.
Object: It is an instance of the Class. In simple words, it is the blueprint of the Class.
// header files
class Class_name
{
/*
Access specifier
public variables: can be accessed from everywhere
protected variables: can be accessed by the classes of the same package
private variables: can be accessed within the same class only.
->This is helpful when you learn the concept of Abstraction in OOPS.
*/
public:
// data variables
int variable_A;
// member functions
void print_function()
{
cout << "Value of variable is :" << variable_A;
}
};
main() {
// declaring object <Syntax: Class_name object_name>
Class_name object;
/*accessing the variables in class and assigning value to it via object*/
object.variable_A= 20;
// accessing member function in class
object.print_function();
}
Now we will cover the four main concepts in OOPS.
- Encapsulation and Abstraction:
In a nutshell, Encapsulation means hiding your data in a package. Abstraction displaying only essential information and hiding the unnecessary details from the client/user.
Create a separate header file in which you would define your entire class. Then you can access the components of your class using the objects in your main function.
// header file header.h
#include <iostream>
using namespace std ;
// we are defining a class in our header file
class Classtwo
{
private: // for data abstraction
int var = 5;
public :
int functionOne(); // declaring functionOne inside class
};
int Classtwo::functionOne() // defining functionOne outside class
{
cout << "functionOne is called(in header file)\n";
}
//main.cpp
// other header files
#include "header.h"
// namespace...
main(){
/* class Classtwo is in header file*/
Classtwo objectOne;
objectOne.functionOne();
cout<< objectOne.var; // would output the value of var
}
- Inheritance:
In a nutshell, the derived class inherits properties from the base class.
//header files
class Base // parent class
{
public :
int number =5;
};
class Derived: public Base // child class
{
public :
void printFunction()
{
cout<<"Hello World";
}
};
main(){
Derived obj; /*object of 'Derived' class can access public components of 'Base ' class*/
cout<< obj.number ;
//would output the number which is in Base class
- Polymorphism:
In a nutshell, it means having different forms. There are two types of polymorphism.
-> Runtime Polymorphism:
It happens when we override a function in the program.
// header files
class Virtual_one
{
public :
int fun_One()
{
cout<<"fun_One works in v1\n";
}
};
class Virtual_two : public Virtual_one
{
public :
int fun_One()
{
cout<<"fun_One works in v2\n";
}
virtual int fun_()
// 'virtual' is used for late binding and runtime polymorphism.
{
cout<<"fun_ works in v2\n";
}
};
class Virtual_three : public Virtual_two // inheritance
{
int fun_()
{
cout<<"fun_works in v3\n";
}
};
main()
{
Virtual_one objA;
Virtual_two objBA , *objBB = new Virtual_two();
/*defining pointer object BB*/
Virtual_three objC;
objBB = &objC;
/*objBB pointer of Virtual_two carries address of objC*/
objA.fun_One();
/*fun_One of Virtual_one would be accessed as objA is of that class*/
objBA.fun_One();
/*fun_One of Virtual_two would be accessed as objBA is of that class*/
objBB->fun_();
/*fun_ function is in Virtual_two and Virtual_three classes, we have used 'virtual' keyword for this*/
/* Note:
HERE objBB pointer(of Virtual_two class) carries address of objC(of Virtual_three class). So in objBB->fun_(); The fun_() of Virtual_two class would be working, as objBB pointer belongs to that class.
But when you add the keyword 'virtual' : The fun_() of Virtual_three class would work. */
-> Compiletime Polymorphism:
It happens when we overload a function or an operator in the program.
Consider a case of Operator Overloading:
// header files
class Op_ovrload
{
int numberA;
int numberB ;
public :
int inputNum()
{
cin >> numberA >> numberB ;
/*writing cin statements in class/header file is considered a bad practice though here it's just for simplicity of code*/
}
// Without Overloading
Op_ovrload addTheSet(Op_ovrload tempObj)
{
Op_ovrload takeT_Obj ;
takeT_Obj.numberA = numberA + tempObj.numberA;
takeT_Obj.numberB = numberB + tempObj.numberB;
return takeT_Obj;
}
// With Overloading
Op_ovrload operator + (Op_ovrload tempObj)
{
// tempObj is loaded as objB
Op_ovrload takeT_Obj ;
takeT_Obj.numberA= numberA + tempObj.numberA
takeT_Obj.numberB = numberB + tempObj.numberB;
return takeT_Obj;
}
};
main()
{
Op_ovrload objA ,objB , objC , objD;
// we would load values in objA and objB
objA.inputNum();
objB.inputNum();
objC = objA.addTheSet(objB);
objD = objA + objB;
/*objC and objD would output the same value. Here '+' has been overloaded*/
}
Consider the other case of function overloading:
// header files
void printFun(int number) {
cout << " Value is" << number;
}
void printFun(double num) {
cout << "Value is " << num;
}
/*Hence we can see the function is overloaded.
The same name of functions with different parameters passed. */
main()
{
printFun(320);
printFun(48.95);
}
With this, we come to an end covering the basic concepts.
Hope this article has been helpful!