The concepts are actually pretty simple:
Classes - Classes are used to group together data and behavior. For example, the builtin int type knows how the data is stored for its variables, but also knows what operations can be performed on that data. Classes give us programmers the ability to write our own data types like that more easily. A class is like the int type and an object is like a variable of int.
Encapsulation - The concept of grouping together data and behavior that classes help to implement.
Inheritance - The ability of one class to extend another by being given data and behavior defined in another class. The new (child) class can also define its own data and behavior as well. For example, I inherited blond hair from my mother (data), but my foul temper is my own (behavior).
Polymorphism - Also called dynamic-binding, polymorphism is the ability of an object of a child class to act as if it were an object of its parent class. For example, if I had a class hierarchy:
Code:
#include <iostream>
using namespace std;
class base {
public:
virtual void whoami() { cout<<"I am base"<<endl; }
};
class derived: public base {
public:
void whoami() { cout<<"I am derived"<<endl; }
};
int main()
{
base b;
derived d;
b.whoami();
d.whoami();
base *rb = &b;
base *rd = &d;
rb->whoami();
rd->whoami();
}
Despite being a pointer to base, rd still prints the correct string. Dynamic-binding chose the proper class type. Without dynamic-binding (through the use of virtual functions), this wouldn't have worked:
Code:
#include <iostream>
using namespace std;
class base {
public:
void whoami() { cout<<"I am base"<<endl; }
};
class derived: public base {
public:
void whoami() { cout<<"I am derived"<<endl; }
};
int main()
{
base b;
derived d;
b.whoami();
d.whoami();
base *rb = &b;
base *rd = &d;
rb->whoami();
rd->whoami();
}
That's basically all there is to it. Actually using object-orientation is more complex, but the underlying principles are relatively simple.