Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a sensible difference between having class inheritence and having a base class as a data member in derived class?

I am still a bit new to object-oriented paradigm, and as such one thing about OOP clouds my mind. This may sound as a naive question with an obvious answer, and it may very well be one, but what are the differences between the following two cases:

case 1:

class A
{
public:
    A() = default; 
    A(int i) : data_point(i) {}; 
    virtual int process_data_point();

protected: 
    int data_point=0;
};

class B : public A
{
public:
    int process_data_point() override;
};

case 2:

class A
{
int data_point=0;

public:
    A() = default; 
    A(int i) : data_point(i) {}; 
    int process_data_point();
};


class B
{
public:
    A process_data_point_in_a_different_way();
    A data_point
};

I mean, I know that case 1 deals with inheritance, that being in the spirit of OOP, but I cannot escape the feeling that one can also emulate inheritance by just taking the base class and defining the new class which contains data members of the base class, with some additional functionality (as sketched in case 2). I am aware that emulating inheritance on a long run may end up being too complex (especially if one ends up with having some unwanted functionality from data member class), but I would expect that for some simple cases inheritance emulation works just fine.

Can someone elaborate more pedagogically on this? Is the idea about emulation inherently bad one, or does it make sense in some cases?

like image 821
Akhaim Avatar asked Oct 14 '25 14:10

Akhaim


1 Answers

Difference 1

Under "inheritance" subject there is another subject which called "polymorphism" - The ability to relate to different objects in the same way. When you use the inheritance way, you can make interface class, and in the future use it in polymorphism situation. Have a quick look on this code:

class BaseClass {
public:
    virtual void action() = 0;
};

class A : public BaseClass {
public:
    void action() {
        cout << "A class" << endl;
    }
};

class B : public BaseClass {
public:
    void action() {
        cout << "B class" << endl;
    }
};

In this case, we have 3 classes. BaseClass that includes abstract function "action", and two inherit classes. The following "main" function show how to use them in polymorphism way:

int main() {
    A a;
    B b;
    vector<BaseClass*> all = vector<BaseClass*>();
    all.push_back(&a);
    all.push_back(&b);

    for (size_t i = 0; i < all.size(); i++) {
        all[i]->action();
    }
}

The output will be:

A class
B class

But look, I didn't call a.action() or b.action()- I called them both in a loop all[i]->action(). You can't do this without inheritance.

Difference 2

"Protected" privilege in classes give the access only for the class itself and the inherit classes. Let's have a look on another example:

class BaseClass {
private:
    void private_method() {
        cout << "Base class private method" << endl;
    }
protected:
    void protected_method() {
        cout << "Base class protected method" << endl;
    }
public:
    void public_method() {
        cout << "Base class public method" << endl;
    }
};

Assume we have this class, which includes private_method, protected_method, and public_method. Now we have two different classes. The class A that inherit BaseClass and class B that include BaseClass. Let's see which methods we can use in each class:

class A : public BaseClass {
public:
    void test_privileges() {
        //this->private_method();   // Compilation error!
        this->protected_method();
        this->public_method();
    }
};

class B {
private:
    BaseClass bc;

public:
    void test_privileges() {
        //bc.private_method();      // Compilation error!
        //bc.protected_method();    // Compilation error!
        bc.public_method();
    }
};

As you can see, there is a protection difference between inherit a class and includes it.

Difference 3

When you design a code, you want it to be as clear as possible to everyone. To do this, you have to keep on a logical flow inside your code. There is a logical difference between inherit a class an includes it. When you are inherit a class you can say that the heiress class is the heritage class, for example:

class Animal {};
class Dog : public Animal {};
class Cat : public Animal {};

The Dog is an Animal -> So Dog class have to inherit the Animal class. When you include a class inside another one, you can say: The contains class have the includes class, for example:

class Tail {};
class Eye {};
class Dog {
private:
    Tail tail;
    Eye eye;
};

The Dog have a tail. -> So Dog class contains Tail class. The Dog have an eye. -> So Dog class contains Eye class.

like image 200
CoralK Avatar answered Oct 17 '25 02:10

CoralK



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!