Ad

Inheritance

Inheritance

 INHERITANCE

The capability of a class to derive properties and characteristics from another class is called Inheritance. Inheritance is one of the most important features of Object-Oriented Programming.
In such a way, you can reuse, extend or modify the attributes and behaviors which are defined in other class.
  • Sub Class: The class that inherits properties from another class is called Subclass or Derived Class or Child class.
  • Super Class: The class whose properties are inherited by sub-class is called Base Class or Superclass or Parent Class.




Advantages of Inheritance

  • Code reusability: Now you can reuse the members of your parent class. So, there is no need to define the member again. So less code is required in the class.
  • Using inheritance, we have to write the functions only one time instead of three times as we have inherited the rest of the three classes from the base class.
  • Inheritance promotes reusability. When a class inherits or derives another class, it can access all the functionality of inherited class.
  • Reusability enhanced reliability. The base class code will be already tested and debugged.
  • As the existing code is reused, it leads to less development and maintenance costs.
  • Inheritance makes the sub classes follow a standard interface.
  • Inheritance helps to reduce code redundancy and supports code extensibility.
  • Inheritance facilitates creation of class libraries.

Disadvantages of Inheritance

  • Inherited functions work slower than normal function as there is indirection.
  • Improper use of inheritance may lead to wrong solutions.
  • Often, data members in the base class are left unused which may lead to memory wastage.
  • Inheritance increases the coupling between base class and derived class. A change in base class will affect all the child classes.

MODES OF INHERITANCE

The visibility mode specifies whether the features of the base class are publicly inherited or privately inherited. It can be public, protected, or private. Modes of Inheritance are as follows:
  • Public mode: If we derive a subclass from a public base class. Then the public member of the base class will become public in the derived class and protected members of the base class will become protected in the derived class.
  • Protected mode: If we derive a subclass from a Protected base class. Then both public members and protected members of the base class will become protected in the derived class.
  • Private mode: If we derive a subclass from a Private base class. Then both public members and protected members of the base class will become Private in the derived class.

Note: The private members in the base class cannot be directly accessed in the derived class, while protected members can be directly accessed. For example, Classes B, C and D all contain the variables x, y and z in below example. It is just question of access.

The below table summarizes the above three modes and shows the access specifier of the members of base class in the sub class when derived in public, protected and private modes:



The visibility modes are also known as Access Specifiers.

TYPES OF INHERITANCE

C++ supports 5 types of Inheritance:
  1. Single inheritance
  2. Multiple inheritance
  3. Hybrid inheritance
  4. Multi-level inheritance
  5. Hierarchical inheritance


Single inheritance 

Single inheritance is defined as the inheritance in which a derived class is inherited from only one base class. In single inheritance, a class is allowed to inherit from only one class. i.e. one subclass is inherited by one base class only.


                                      

Where 'A' is the base class, and 'B' is the derived class.

Example,

#include <iostream>  
using namespace std;  
class Animal 
{  
   public:  
         void eat() 
        {   
            cout<<''Eating...''<<endl;   
        }    
};  
class Dog: public Animal    
{    
    public:  
        void bark()
        {  
            cout<<''Barking...'';   
        }    
 };   

int main(void
{  
        Dog d1;  
        d1.eat();  
        d1.bark();  
        return 0;  
}  

Output:

Eating...
Barking...

This is an example of Single Inheritance.

Multiple inheritance 

Multiple inheritance is the process of deriving a new class that inherits the attributes from two or more classes. Multiple Inheritance is a feature of C++ where a class can inherit from more than one classes. i.e one sub class is inherited from more than one base classes.

  







Where 'B' and 'C' are the base classes, and 'A' is the derived class.

Example,

#include <iostream>  
using namespace std;  
class A  
{  
        protected:  
             int a;  
        public:  
            void get_a(int n)  
            {  
                    a = n;  
            }  
};  
  
class B  
{  
        protected:  
            int b;  
        public:  
            void get_b(int n)  
            {  
                    b = n;  
            }  
};  

class C : public A,public B  
{  
       public:  
            void display()  
            {  
                    std::cout << "The value of a is : " <<a<< std::endl;  
                    std::cout << "The value of b is : " <<b<< std::endl;  
                    std::cout<<"Addition of a and b is : "<<a+b;  
            }  
};  

int main()  
{  
       C c;  
       c.get_a(10);  
       c.get_b(20);  
       c.display();  
  
        return 0;  
}  

Output:

The value of a is : 10
The value of b is : 20
Addition of a and b is : 30

In the above example, class 'C' inherits two base classes 'A' and 'B' in a public mode

This is an example of Multiple Inheritance.

Multi-level inheritance 

Multilevel inheritance is a process of deriving a class from another derived class. In this type of inheritance, a derived class is created from another derived class. When one class inherits another class which is further inherited by another class, it is known as multi level inheritance in C++. Inheritance is transitive so the last derived class acquires all the members of all its base classes.

         


Example,

#include <iostream>  
using namespace std;  
class Animal 
{  
       public:  
             void eat() 
            {   
                    cout<<"Eating..."<<endl;   
            }    
};  
class Dog: public Animal   
{    
       public:  
             void bark()
             {  
                    cout<<"Barking..."<<endl;   
             }    
};   
class BabyDog: public Dog   
{    
       public:  
             void weep() 
             {  
                    cout<<"Weeping...";   
             }        
};   

int main(void
{  
        BabyDog d1;  
        d1.eat();  
        d1.bark();  
        d1.weep();  
        return 0;  
}  

OUTPUT:

Eating...
Barking...
Weeping...

This is an example of Multi-LEVEL Inheritance.


Hierarchical inheritance

Hierarchical inheritance is defined as the process of deriving more than one class from a base class. In this type of inheritance, more than one sub class is inherited from a single base class. i.e. more than one derived class is created from a single base class.

 




Example,

#include <iostream>  
using namespace std;  
class Shape                 // Declaration of base class.  
{  
        public:  
            int a;  
            int b;  
            void get_data(int n,int m)  
            {  
                    a= n;  
                    b = m;  
            }  
};  

class Rectangle : public Shape  // inheriting Shape class  
{  
        public:  
            int rect_area()  
            {  
                    int result = a*b;  
                    return result;  
            }  
};  

class Triangle : public Shape    // inheriting Shape class  
{  
        public:  
            int triangle_area()  
            {  
                    float result = 0.5*a*b;  
                    return result;  
            }  
};  

int main()  
{  
        Rectangle r;  
        Triangle t;  
        int length,breadth,base,height;  
        std::cout << "Enter the length and breadth of a rectangle: " << std::endl;  
        cin>>length>>breadth;  
        r.get_data(length,breadth);  
        int m = r.rect_area();  
        std::cout << "Area of the rectangle is : " <<m<< std::endl;  
        std::cout << "Enter the base and height of the triangle: " << std::endl;  
        cin>>base>>height;  
        t.get_data(base,height);  
        float n = t.triangle_area();  
        std::cout <<"Area of the triangle is : "  << n<<std::endl;  
        return 0;  
}

OUTPUT:

Enter the length and breadth of a rectangle:
23  
20  
Area of the rectangle is : 460          
Enter the base and height of the triangle:  
2   
5
Area of the triangle is : 5 

This is an example of Hierarchical Inheritance.

Hybrid Inheritance

Hybrid inheritance is a combination of more than one type of inheritance. Hybrid (Virtual) Inheritance is implemented by combining more than one type of inheritance. For example: Combining Hierarchical inheritance and Multiple Inheritance. Below image shows the combination of hierarchical and multiple inheritance:

 





Example,

#include <iostream>  
using namespace std;  
class A  
{  
        protected:  
            int a;  
        public:  
            void get_a()  
            {  
                   std::cout << "Enter the value of 'a' : " << std::endl;  
                   cin>>a;  
            }  
};  
  
class B : public A   
{  
        protected:  
            int b;  
        public:  
            void get_b()  
            {  
                    std::cout << "Enter the value of 'b' : " << std::endl;  
                   cin>>b;  
            }  
};  
class C   
{  
        protected:  
            int c;  
        public:  
            void get_c()  
            {  
                    std::cout << "Enter the value of c is : " << std::endl;  
                    cin>>c;  
            }  
};  
  
class D : public B, public C  
{  
        protected:  
            int d;  
        public:  
            void mul()  
            {  
                     get_a();  
                     get_b();  
                     get_c();  
                     std::cout << "Multiplication of a,b,c is : " <<a*b*c<< std::endl;  
            }  
};  

int main()  
{  
        D d;  
        d.mul();  
        return 0;  

OUTPUT: 

Enter the value of 'a' :
10              
Enter the value of 'b' :    
20      
Enter the value of c is :   
30  
Multiplication of a,b,c is : 6000


Virtual Base Class

Virtual base classes are used in virtual inheritance in a way of preventing multiple “instances” of a given class appearing in an inheritance hierarchy when using multiple inheritances.

Need for Virtual Base Classes:
Consider the situation where we have one class A .This class is A is inherited by two other classes B and C. Both these class are inherited into another in a new class D as shown in figure below.





As we can see from the figure that data members/function of class A are inherited twice to class D. One through class B and second through class C. When any data / function member of class A is accessed by an object of class D, ambiguity arises as to which data/function member would be called? One inherited through B or the other inherited through C. This confuses compiler and it displays error.

Example: To show the need of Virtual Base Class in C++

#include <iostream>
using namespace std;
  
class A {
public:
    void show()
    {
        cout << "Hello form A \n";
    }
};
  
class B : public A {
};
  
class C : public A {
};
  
class D : public B, public C {
};
  
int main()
{
    D object;
    object.show();
}
Compile Errors:
prog.cpp: In function 'int main()':
prog.cpp:29:9: error: request for member 'show' is ambiguous
  object.show();
         ^
prog.cpp:8:8: note: candidates are: void A::show()
   void show()
        ^
prog.cpp:8:8: note:                 void A::show()

How to resolve this issue?

To resolve this ambiguity when class A is inherited in both class B and class C, it is declared as virtual base class by placing a keyword virtual as :

Syntax for Virtual Base Classes:

  • Syntax 1:
                class B : virtual public A 
                

                }; 

  • Syntax 2: 
                class C : public virtual A 
                

                };

Note: Virtual can be written before or after the public. Now only one copy of data/function member will be copied to class C and class B and class A becomes the virtual base class.
Virtual base classes offer a way to save space and avoid ambiguities in class hierarchies that use multiple inheritances. When a base class is specified as a virtual base, it can act as an indirect base more than once without duplication of its data members. A single copy of its data members is shared by all the base classes that use virtual base.

Example 1

#include <iostream>
using namespace std;
  
class A {
public:
    int a;
    A() // constructor
    {
        a = 10;
    }
};
  
class B : public virtual A {
};
  
class C : public virtual A {
};
  
class D : public B, public C {
};
  
int main()
{
    D object; // object creation of class d
    cout << "a = " << object.a << endl;
  
    return 0;
}

Output:
a = 10
Explanation: The class A has just one data member a which is public. This class is virtually inherited in class B and class C. Now class B and class C becomes virtual base class and no duplication of data member a is done.

Example 2:

#include <iostream>
using namespace std;
  
class A {
public:
    void show()
    {
        cout << "Hello from A \n";
    }
};
  
class B : public virtual A {
};
  
class C : public virtual A {
};
  
class D : public B, public C {
};
  
int main()
{
    D object;
    object.show();
}

Output:
Hello from A

Abstract Class

Abstract Class A class, which serves only as a base class from which other classes are derived, but no objects of this base class type exist, is known as Abstract Class.

For more information read the following articles:

EXECUTION OF CONSTRUCTORS

When classes are inherited, the constructors are called in the same order as the classes are inherited. If we have a base class and one derived class that inherits this base class, then the base class constructor (whether default or parameterized) will be called first followed by the derived class constructor.

Whenever we create an object of a class, the default constructor of that class is invoked automatically to initialize the members of the class.

If we inherit a class from another class and create an object of the derived class, it is clear that the default constructor of the derived class will be invoked but before that the default constructor of all of the base classes will be invoke, i.e the order of invocation is that the base class’s default constructor will be invoked first and then the derived class’s default constructor will be invoked.

Why the base class’s constructor is called on creating an object of derived class?

To understand this you will have to recall your knowledge on inheritance. What happens when a class is inherited from other? The data members and member functions of base class comes automatically in derived class based on the access specifier but the definition of these members exists in base class only. So when we create an object of derived class, all of the members of derived class must be initialized but the inherited members in derived class can only be initialized by the base class’s constructor as the definition of these members exists in base class only. This is why the constructor of base class is called first to initialize all the inherited members.

EXECUTION OF DESTRUCTORS


When a derived object is destroyed, its destructor is called first, followed by the destructor for the base class. C++ constructors are executed in the order of their derivation. Destructors are executed in reverse order of derivation.

Problems with Inheritance:

  1. Single inheritance
  2. Multiple inheritance
  3. Hybrid inheritance
  4. Multi-level inheritance
  5. Hierarchical inheritance


KEY-NOTES

  • The default visibility in a class is private.
  • A subclass can derive itself as public, private, or protected.
  • The derived class constructor is responsible for invoking (and passing arguments to) the base class constructor.
  • To make a private member of the base class, declare it under a protected section of the base class.
  • A class may contain objects of another class inside it. This situation is called nesting of objects and in such a situation, the contained objects are constructed first before constructing the objects of the enclosing class.
  • The visibility mode controls the visibility and availability of inherited base class members in the derived class.
  • Actually, a derived class inherits all the members of a base class; however, the derived class has access privilege only to the non-private members of the base class.
  • Access specifiers control access of members within a class whereas visibility modes control access of inherited members within the subclass.
  • Derive publicly when the situation wants the derived class to have all the attributes of the base class, plus some extra attributes.
  • Derive privately when the derived class is required to use some attributes of the class and these inherited features are intended not to be inherited further.
  • Derive protected when the features are required to be hidden from the outside world and at the same time required to be inheritable.
  • When an object of a derived class is created, first the base class constructor is invoked, followed by the derived class constructors. When an object of a derived class expires, first the derived class destructor is invoked, followed by the base class destructor.
  • One interesting thing that you must know is that if you declare a class without any data member then what will its size be? Well, the class will still have the size of 1 byte. Check it out on your own.
  • The private members of the base class are visible in the derived class but they are not directly accessible.
  • You cannot deny access to certain members of a Base class when inheriting publicly.
  • Abstract Class A class, which serves only as a base class from which other classes are derived, but no objects of this base class type exist, is known as Abstract Class.
  • When a derived-class function has the same name as that if its base-class'-member-function (i.e. redefined in derived class), the derived class' member function shadows/hides the base class's inherited function and this situation is known as function overriding.
  • The derived class can use all the inherited members in the same way it uses its own members.
  • In multiple inheritance, the base classes are constructed in the order in which they appear in the declaration of the derived class.
  • Containership or Containment or Aggregation:
    • When a class contains objects of other class types as its member, it is referred to as Containership or Containment or Aggregation.
  • The constructor for a member object of a class is invoked implicitly (through the object name) and the constructor for the base class is invoked explicitly (through the class name).
  • When a class inherits from another class, the derived class has is-a relationship with its base class. When a class contains object of another class-type, then containing / enclosing class has has-a relationship with contained / enclosed class.

0 Response to "Inheritance"

Post a Comment

If you have any doubts, please let me know...

Ads Atas Artikel

Ads Center 1

Ads Center 2

Ads Center 3