It has been a long time since I didn't write an article. Now, let me continue to write more for C++. I wrote about the crash course in C and C++. In this article, I wrote about Object-Oriented Programming in C++.
It is easy to apply OOP in C++ because of the language itself. In other words, C++ is a version of C but with an OOP feature. There is no "interface" in C++ that may cause you to be confused because that can be achieved by "class" only. Let's code!
#include<iostream>usingnamespacestd;classAnimal{public:stringname;intfeets;boolhasPaws;};intmain(){Animalcat;cat.name="Cat";cat.feets=4;cat.hasPaws=false;cout<<cat.name<<" has "<<cat.feets<<" feets."<<endl;if(cat.hasPaws){cout<<cat.name<<" has paws."<<endl;}Animaldog;dog.name="Dog";dog.feets=4;dog.hasPaws=true;cout<<dog.name<<" has "<<dog.feets<<" feets."<<endl;if(dog.hasPaws){cout<<dog.name<<" has paws."<<endl;}return0;}
Let's start with creating a class with its properties. In coding a class of C++, defining an access modifier is a must. We can start with the public. We let those properties be accessible to the public.
Let's compile and run it with the command g++ main.cpp -o main && ./main. You can see more explanations about the basic syntaxes on the C/C++ Crash Course.
Methods
We did repetition while printing. Let's create a method for it.
#include<iostream>usingnamespacestd;classAnimal{public:stringname;intfeets;boolhasPaws;voidprint(){cout<<name<<" has "<<feets<<" feets."<<endl;if(hasPaws){cout<<name<<" has paws."<<endl;}}};intmain(){Animalcat;cat.name="Cat";cat.feets=4;cat.hasPaws=false;cat.print();Animaldog;dog.name="Dog";dog.feets=4;dog.hasPaws=true;dog.print();}
#include<iostream>usingnamespacestd;classAnimal{public:stringname;intfeets;boolhasPaws;voidprint(){cout<<name<<" has "<<feets<<" feets."<<endl;if(hasPaws){cout<<name<<" has paws."<<endl;}}};classMonster:publicAnimal{public:vector<string>abilities;};classLegend{public:stringmyth;};classMythical:publicMonster,publicLegend{public:stringstory;};intmain(){Mythicaldragon;dragon.name="Dragon";dragon.feets=4;dragon.hasPaws=true;dragon.abilities.push_back("Nuclear blast");dragon.abilities.push_back("Ice smoke");dragon.myth="Appears in the folklore.";dragon.story="From the hidden world.";dragon.print();return0;}
C++ is cool. It supports multiple inheritance. From the example above, we create a dragon from Mythical and that dragon has all the properties from its parents.
We can define the abilities like this, dragon.abilities = {"Nuclear blast", "Ice smoke"}. But we need at least a C++11 compiler to compile it, g++ -std=c++11 main.cpp -o main && ./main.
#include<iostream>usingnamespacestd;classAnimal{public:stringdescription;};classMonster:publicAnimal{};classLegend:publicAnimal{};classMythical:publicMonster,publicLegend{};intmain(){Mythicaldragon;dragon.description="This should be ambiguous.";return0;}
Could you compile the code above and see what you get? That error is an error of ambiguity. The compiler didn't know where she got the description.
To solve that, let's make the classes derived from virtual classes.
Replace the line 10 with class Monster: public virtual Animal.
Replace the line 14 with class Legend: public virtual Animal.
We added virtual syntax to the parent class. Now, the ambiguity is solved.
#include<iostream>usingnamespacestd;classAnimal{public:voidprint();};classMonster:publicAnimal{};classMythical:publicAnimal{public:voidprint(){cout<<"Mythical is a part of animal."<<endl;}};intmain(){Monstermonster;Mythicalmythical;monster.print();mythical.print();return0;}
Let's compile the code above and what will you get? That is an error of an undefined symbol. What's wrong? That is because the Animal is an abstract class. On line 7, we can see a print method without the implementation, which means the children from that class should implement the print method.
Of course, we need to write the implementation of the print method to solve that.
#include<iostream>usingnamespacestd;classAnimal{public:stringname;intfeets;boolhasPaws;voidprint(){cout<<name<<" has "<<feets<<" feets."<<endl;if(hasPaws){cout<<name<<" has paws."<<endl;}}};classMonster:publicAnimal{public:vector<string>abilities;voidprint(){cout<<name<<" is a monster!!!"<<endl;cout<<name<<" has:"<<endl;for(stringability:abilities){cout<<"- "<<ability<<endl;}}};intmain(){Monsterdragon;dragon.name="Dragon";dragon.feets=4;dragon.hasPaws=true;dragon.abilities.push_back("Nuclear blast");dragon.abilities.push_back("Ice smoke");dragon.print();return0;}
Let's try to remove the print method from the Monster class. We will get no error. Because the Animal, the parent of the Monster, already has the print method.
The example above is about Polymorphism. The children replace the details of the parent methods.
#include<iostream>usingnamespacestd;classProperties{public:virtualvoidsetName(stringname)=0;virtualstringgetName()=0;virtualvoidsetFeets(intfeets)=0;virtualintgetFeets()=0;virtualvoidsetHasPaws(boolhasPaws)=0;virtualboolgetHasPaws()=0;};classAnimal:publicProperties{public:stringname;intfeets;boolhasPaws;voidsetName(stringname){this->name=name;}stringgetName(){returnname;}voidsetFeet(intfeets){this->feets=feets;}intgetFeet(){returnfeets;}voidsetHasPaws(boolhasPaws){this->hasPaws=hasPaws;}boolgetHasPaws(){returnhasPaws;}voidprint(){cout<<name<<" has "<<feets<<" feets."<<endl;if(hasPaws){cout<<name<<" has paws."<<endl;}}};classMonster:publicAnimal{public:vector<string>abilities;voidsetName(stringname)override{this->name=name;}stringgetName()override{returnname;}voidsetFeets(intfeets)override{this->feets=feets;}intgetFeets()override{returnfeets;}voidsetHasPaws(boolhasPaws)override{this->hasPaws=hasPaws;}boolgetHasPaws()override{returnhasPaws;}voidprint(){cout<<name<<" is a monster!!!"<<endl;cout<<name<<" has:"<<endl;for(stringability:abilities){cout<<"- "<<ability<<endl;}}};intmain(){Monsterdragon;dragon.name="Dragon";dragon.feets=4;dragon.hasPaws=true;dragon.abilities.push_back("Nuclear blast");dragon.abilities.push_back("Ice smoke");dragon.print();return0;}
In C++, an interface is an abstract class with pure virtual functions. It is strong. Let's try to remove any method of Properties from the Monster class, you will get an error even though that method is already defined in its parent, the Animal class.
Constructor
By the way, let's create a constructor for the Monster class. So, we can initialize an object in simple and short.
#include<iostream>usingnamespacestd;classProperties{public:virtualvoidsetName(stringname)=0;virtualstringgetName()=0;virtualvoidsetFeets(intfeets)=0;virtualintgetFeets()=0;virtualvoidsetHasPaws(boolhasPaws)=0;virtualboolgetHasPaws()=0;};classAnimal:publicProperties{protected:stringname;intfeets;boolhasPaws;public:voidsetName(stringname){this->name=name;}stringgetName(){returnname;}voidsetFeet(intfeets){this->feets=feets;}intgetFeet(){returnfeets;}voidsetHasPaws(boolhasPaws){this->hasPaws=hasPaws;}boolgetHasPaws(){returnhasPaws;}voidprint(){cout<<name<<" has "<<feets<<" feets."<<endl;if(hasPaws){cout<<name<<" has paws."<<endl;}}};classMonster:publicAnimal{public:vector<string>abilities;Monster(stringname,intfeets,boolhasPaws,vector<string>abilities){this->name=name;this->feets=feets;this->hasPaws=hasPaws;this->abilities=abilities;}voidsetName(stringname)override{this->name=name;}stringgetName()override{returnname;}voidsetFeets(intfeets)override{this->feets=feets;}intgetFeets()override{returnfeets;}voidsetHasPaws(boolhasPaws)override{this->hasPaws=hasPaws;}boolgetHasPaws()override{returnhasPaws;}voidprint(){cout<<name<<" is a monster!!!"<<endl;cout<<name<<" has:"<<endl;for(stringability:abilities){cout<<"- "<<ability<<endl;}}};intmain(){Monsterdragon("Dragon",4,true,{"Nuclear blast","Ice smoke"});dragon.print();return0;}