Inheritance/Polymorphism  «Prev  Next»
Lesson 5 A derived class and the "IS-A relationship"
Objective Several pairs of example classes fit definition

IS-A relationship in Object Oriented Programming

Determine whether several pairs of example classes fit the definition of class and subclass. In our student/graduate student example, grad_student is the derived class and student is the base class. The use of the keyword public following the colon in the derived class header means that the protected and public members of student are to be inherited as protected and public members of grad_student. Members that are private are inaccessible. This is referred to as public inheritance.
Public inheritance also means that the derived class grad_student is a subtype or subclass of student. Thus, a graduate student is a student, but a student does not have to be a graduate student. This subtyping relationship is called the ISA relationship. This is also called interface inheritance. A derived class is a modification of the base class that inherits the public and protected members of the base class. The only members that cannot be inherited are constructors and any member function that overloads the assignment operator. Let us look at an example of public inheritance using the student and grad_student classes.
`Base` and `Derived` classes using:
✅ Updated C++ best practices (as of 2025), including:
  • Modern class naming conventions (PascalCase)
  • enum class instead of unscoped enums
  • Use of std::string instead of char* and fixed-size C-style arrays
  • Constructor initialization lists
  • Virtual function for polymorphic behavior (print())

This code is written to compile and run on MS Visual Studio 2019 or higher with a C++17 or later standard (including C++23).
✅ Rewritten Code
#include <iostream>
#include <string>

enum class AcademicYear { Freshman, Sophomore, Junior, Senior, Graduate };

class Student {
public:
    Student(const std::string& name, int id, double gpa, AcademicYear year)
        : studentId(id), gpa(gpa), year(year), name(name) {}

    virtual void print() const {
        std::cout << "Name: " << name << "\n"
                  << "ID: " << studentId << "\n"
                  << "GPA: " << gpa << "\n"
                  << "Year: " << static_cast<int>(year) << "\n";
    }

protected:
    int studentId;
    double gpa;
    AcademicYear year;
    std::string name;
};

enum class SupportType { TA, RA, Fellowship, Other };

class GradStudent : public Student {
public:
    GradStudent(const std::string& name, int id, double gpa, AcademicYear year,
                SupportType support, const std::string& dept, const std::string& thesis)
        : Student(name, id, gpa, year), support(support), department(dept), thesis(thesis) {}

    void print() const override {
        Student::print();
        std::cout << "Support: " << static_cast<int>(support) << "\n"
                  << "Department: " << department << "\n"
                  << "Thesis: " << thesis << "\n";
    }

protected:
    SupportType support;
    std::string department;
    std::string thesis;
};

✅ Example Usage in `main()`
int main() {
    GradStudent gs("Alice Johnson", 202301, 3.92, AcademicYear::Graduate,
                   SupportType::RA, "Physics", "Quantum Entanglement Simulation");

    gs.print();

    return 0;
}

🔍 Improvements Made Based on 2025 C++ Practices
Feature Legacy Code Modernized Code (2025)
Class Naming student, grad_student Student, GradStudent
Enum Usage enum year, enum support enum class AcademicYear, SupportType
String Handling char name[30] std::string name
Function Overriding Just redefined Used virtual + override
Constructor Style Only declarations Used initialization lists
Encapsulation/Access protected for all Kept protected for inheritance
Output Format None std::cout in print()

  • Protected Members
    The student members student_id, gpa, name, y, and print() are inherited by grad_student. In the class student, these members are protected. This makes them visible to the derived class, grad_student, but otherwise treated as private. Notice that the student constructor is not inherited, even though it is a public member of the base class.

Distinguish between "is-a" relationship and "has-a" relationship

The is-a relationship represents inheritance. In an is-a relationship, an object of a derived class also can be treated as an object of its base class. For example, a car is a vehicle, so any attributes and behaviors of a vehicle are also attributes and behaviors of a car. By contrast, the "has-a relationship" represents composition. The folloing link discussses Aggregation. In a "has-a relationship", an object contains one or more objects of other classes as members. For example, a car includes many components. A car has a
  1. steering wheel,
  2. brake pedal, and
  3. transmission.

Derived-class member functions

Derived-class member functions might require access to base-class data members and member functions. A derived class can access the non-private members of its base class. Base-class members that should not be accessible to the member functions of derived classes should be declared private in the base class.
  1. Derived-class member functions might require access to base-class data members and member functions.
    • Derived classes often extend or modify behavior defined in a base class. For this reason, they frequently need access to the base class's members—especially protected or public ones—to reuse or enhance the functionality.
  2. A derived class can access the non-private members of its base class.
    • In C++, the accessibility of base class members in a derived class depends on the access specifier used:
    • Public and protected members of the base class are accessible in the derived class.
    • Private members are not accessible directly in the derived class.
  3. Base-class members that should not be accessible to the member functions of derived classes should be declared private in the base class.
    • This is standard object-oriented practice. Declaring a member as private ensures encapsulation and restricts access only to the base class itself—not even derived classes can access it directly.
Summary:
Base Class Access Specifier Accessible in Derived Class?
public ✅ Yes
protected ✅ Yes
private ❌ No

These principles are foundational in C++ inheritance and encapsulation.
A derived class[1] can change the values of private base-class members, but only through non-private member functions provided in the base class and inherited into the derived class.

Public Inheritance - Quiz

Click the Quiz link below to take a brief multiple-choice quiz on public inheritance.
Public Inheritance - Quiz

Classes Subtypes Exercise

When you have completed the quiz, return here and click the Exercise link to determine whether several pairs of example classes fit the definition of class and subclass.
Classes Subtypes - Exercise

[1]derived class: A derived class is a class created or derived from another existing class.

SEMrush Software