Inheritance/Polymorphism  «Prev  Next»
Lesson 4 A derived class
Objective Describe the General Syntax of a Derived Class and examine an Example

Describe General Syntax of Derived Class

A class can be derived from an existing class using the general form:
class class name:(public| protected| private) base class { 
     member declarations
}; 

  • Visibility of Inherited members:
    One aspect of the derived class is the visibility of its inherited members. The access specifier keywords public, protected, and private are used to specify how the base class members are to be accessible to the derived class. The new keyword protected specifies that a member is accessible to other member functions within its own class and any class immediately derived from the member function's class. When you declare a derived class without a base class access specifier, the derivation is considered private. When a base class is declared private, its public and protected members are considered private members of the derived class, while private functions of the base class are inaccessible to any derived class.

C++ Deviced Class Example

Consider developing a class to represent students at a college or university:
enum year { fresh, soph, junior, senior, grad };

class student {
public:
  student(char* nm, int id, double g, year x);
  void  print() const;
protected:
  int     student_id;
  double  gpa;
  year    y;
  char    name[30];
};

We could write a program that lets the registrar track such students. While the information stored in student objects is adequate for undergraduates, it omits crucial information needed to track graduate students.
Such additional information might include the graduate students' means of support, department affiliations, and thesis topics. Inheritance lets us derive a suitable grad_student class from the base class student as follows:

Three main benefits of using a Derived Class

There are three main benefits to using a derived class:
  1. Code is reusable,
  2. Hierarchy reflects a relationship found,
  3. Polymorphic Mechanisms
  1. First, code is reusable. The grad_student type uses existing, tested code from the student type.
  2. Second, the hierarchy reflects a relationship found in the problem domain. When speaking of students, the special grouping "graduate student" is an outgrowth of the real world and its treatment of this group.
  3. Finally, various polymorphic mechanisms will allow client code to treat grad_student as a subtype of student, simplifying client code while granting it the benefits of maintaining these distinctions among subtypes.

  • A View of Inheritance using a Derived Class
    To the derived class itself, nothing much has changed in terms of how it is written or how it behaves. You can still define methods and data members on a derived class just as you would on a regular class. The previous definition of Sub declares a method called someOtherMethod(). Thus, the Sub class augments the Super class by adding an additional method. A derived class can access public and protected methods and data members declared in its base class as though they were its own, because technically, they are. For example, the implementation of someOtherMethod() on Sub could make use of the data member mProtectedInt, which was declared as part of Super. The following code shows this implementation. Accessing a base class data member or method is no different than if the data member or method were declared as part of the derived
    class.
    void Sub::someOtherMethod()
    {
    cout << "I can access base class data member mProtectedInt." << endl;
    cout << "Its value is " << mProtectedInt << endl;
    }
    

    When access specifiers (public, private, and protected) were introduced, the difference between private and protected may have been confusing. Now that you understand derived classes, the difference should be clear. If a class declares methods or data members as protected, derived classes have access to them. If they are declared as private, derived classes do not have access. The following implementation of someOtherMethod() will not compile because the derived class attempts to access a private data member from the base class.
    void Sub::someOtherMethod()
    {
    cout << "I can access base class data member mProtectedInt." << endl;
    cout << "Its value is " << mProtectedInt << endl;
    cout << "The value of mPrivateInt is " << mPrivateInt << endl; // Error!
    }
    

C++ private Access Specifier

The private access specifier gives you control over how a potential derived class could interact with your class. I recommend that you make all your data members private by default. You can provide public getters and setters if you want to allow anyone to access those data members, and you can provide protected getters and setters if you only want derived classes to access them. The reason to make data members private by default is that this provides the highest level of encapsulation. This means that you can change how you represent your data while keeping the public and protected interface unchanged. Without giving direct access to data members, you can also easily add checks on the input data in your public and protected setters. Methods should also be private by default. Only make those methods public that are designed to be public, and make methods protected if you only want derived classes to have access to them.
enum support { ta, ra, fellowship, other };
class grad_student : public student {
public:
  grad_student
   (char* nm, int id, double g, year x, support t,
    char* d, char* th);
  void  print() const;
protected:
  support s;
  char dept[10];
  char thesis[80];
};

SEMrush Software