This post is about the fundamentals of object-oriented design and includes many examples to demonstrate. Actually, I wrote this post because┬ásometimes I need to recall their name even I can remember the principle. It helps me to remember their name ­čÖé

As you know, applications are developed for our needs and we use algorithms to create them. Generally, different algorithms can be used for a problem, everyone can solve the same problem using a different approach. But the most important thing is using objects and data structures to ease its understandable and development process, also object-oriented provide us a quick re-design and visualization.

1. Class and Object

#include <<iostream>>
using namespace std;

class Person{
public:
	char* name;
	int age;
};

int main() {
	Person person_one;
	person_one.name="Ahmet";
	person_one.age=22;

	cout<<person_one.name<<endl;
	cout<<person_one.age<<endl;
}

2. Inheritance

This word is related to its real meaning, sometimes we want to have classes derived from a base class, so we use inheritance method ­čÖé

#include <<iostream>>;
using namespace std;
class Person{

public:
    char* name;
    int age;

protected:
    int idNumber;

private:
    int secrets;

};

//Engineer has name, age and idNumber fields from Base Class
class Engineer: public Person{
public:
    char* speciality;
    int workingYear;

protected:
    int engID;

private:
    int projects;

};

int main() {
    Person personOne;
    personOne.name="Ahmet";
    personOne.age=22;

    Engineer engineerOne;
    engineerOne.name="Faruk";
    engineerOne.age=23;
    engineerOne.speciality="Hardware";
    engineerOne.workingYear=3;
}

There are some rules about accessing data fields so we use private, protected and public definitions. For details, you can look at here.

3. Overloading

Sometimes we want to use the same function with different parameters, so we use overloading to do this. We define the same function name with different parameters.

#include <iostream>
using namespace std;
class Person{
public:
    char* name;
    int age;

protected:
    int idNumber;

private:
    int secrets;

};

//Engineer has name, age and idNumber fields from Base Class
class Engineer: public Person{
public:
    char* speciality;
    int workingYear;

    void setProjects(){
        this->projects=0;
    }

    void setProjects(int a){
        this->projects=a;
    }

    void setProjects(int a, int b){
        this->projects=a+b;
    }

    int getProjects() const {
        return projects;
    }

protected:
    int engID;

private:
    int projects;
};

int main() {
    Person personOne;
    personOne.name="Ahmet";
    personOne.age=22;

    Engineer engineerOne;
    engineerOne.name="Faruk";
    engineerOne.age=23;
    engineerOne.speciality="Hardware";
    engineerOne.workingYear=3;

    engineerOne.setProjects();
    cout<<engineerOne.getProjects()<<endl;

    engineerOne.setProjects(4);
    cout<<engineerOne.getProjects()<<endl;

    engineerOne.setProjects(7,3);
    cout<<engineerOne.getProjects()<<endl;
}

4. Polymorphism

Sometimes, we have multiple derivatived classes and they all have the common function that is different in details. Let me give you an example; cat and dog are animals, all animals have tell/say function but cats meuw while dogs bark. So, the base class has a method, all derivatived classes has also this common function but these functions do different events.

#include <iostream>
using namespace std;
class Person{
public:
    virtual void doSomething(){
        cout<<"Person is doing..."<<endl; } char* name; int age; protected: int idNumber; private: int secrets; }; //Engineer has name, age and idNumber fields from Base Class class Engineer: public Person{ public: char* speciality; int workingYear; void setProjects(){ this->projects=0;
    }

    void setProjects(int a){
        this->projects=a;
    }

    void setProjects(int a, int b){
        this->projects=a+b;
    }

    int getProjects() const {
        return projects;
    }

    void doSomething(){
        //Person::doSomething();
        cout<<"Engineer is doing..."<<endl;
    }

protected:
    int engID;

private:
    int projects;
};

class Doctor : public Person{
public:
    void doSomething(){
        cout<<"Doctor is doing ..."<<endl; } }; int main() { Person personOne; personOne.name="Ahmet"; personOne.age=22; Engineer engineerOne; engineerOne.name="Faruk"; engineerOne.age=23; engineerOne.speciality="Hardware"; engineerOne.workingYear=3; Doctor doctorOne; doctorOne.name="Dr. Someone"; doctorOne.age=29; Person *personPtr; personPtr=&personOne; personPtr->doSomething();

    personPtr=&engineerOne;
    personPtr->doSomething();

    personPtr=&doctorOne;
    personPtr->doSomething();
}

I prefer to use this method for arrays. Sometimes I have to create an array to store derivated objects together but as you know arrays have a specific type and I have to define it as a base class to keep all of them. When you don’t use “virtual” indicator, the base function is run always for all objects derivatived.

The output without virtual function:

Person is doing...
Person is doing...
Person is doing ...

The output with virtual function:

Person is doing...
Engineer is doing...
Doctor is doing ...

5. Encapsulation

When we want to define some private data in a class, we need to use special methods to access or edit them because we can not access them like regular properties. So we use getter and setter methods. It’s a really simple fundemantal.


#include <iostream>

class Person{
private:
    int secretNumber;
public:
    int getSecretNumber() const {
        return secretNumber;
    }

    void setSecretNumber(int secretNumber) {
        Person::secretNumber = secretNumber;
    }
};

int main() {
    Person ahmet;
    ahmet.setSecretNumber(7);
    std::cout << "Secret number:" << ahmet.getSecretNumber()<< std::endl;
    return 0;
}

This code below shows that we use getter and setter methods for private variables. It is also related to “Abstraction”, the difference between “Abstraction” and “Encapsulation” is the purpose. Here is the detail.

We look at quickly the fundamentals of OOP below, using them always help your coding and design process and also other developers who work with you on the same project can understand your code easily.