Skip to main content

Section 19.12 Designing with Inheritance

Designing in terms of inheritance can take a little more creativity than designing with composition or aggregation. Often times, we have to invent new classes to make an inheritance hierarchy work.
A good process looks like this:
  1. First identify any existing classes that have an is-a relationship. One indication that an is-a relationship might exist is if all of the members of one class A also appear in class B, which has more members. Then A might be a B.
  2. Then look for any other duplicated information. If class A and B have some common members perhaps there is some class C that they both should inherit from. This new β€œdiscovered” class is likely to be an abstract class.
As an example, say we have the following classes representing different kinds of employees and we would like to use inheritance to reuse code. (We will only focus on the member variables and a single method. You can imagine that each class also has getters, setters, and other appropriate methods.)
UML for Salaried, Hourly, and Salesperson classes.
          classDiagram
          class SalariedEmployee {
            -m_name: string
            -m_title: string
            -m_salary: double
            +calculatePay(): double
          }
          class HourlyEmployee {
            -m_name: string
            -m_title: string
            -m_hoursWorked: double
            -m_hourlyRate: double
            +calculatePay(): double
          }
          class Salesperson {
            -m_name: string
            -m_title: string
            -m_salary: double
            -m_sales: double
            +calculatePay(): double
          }
        
      
Figure 19.12.1. UML for Salaried, Hourly, and Salesperson
Looking at that diagram, we can see that Salesperson has everything that SalariedEmployee has, which indicates a potential for inheritance. Does it make sense to say that β€œSalesperson is-a SalariedEmployee”? After considering it, we decide yes. In our system, Salespeople are salaried employees who get a bonus based on their sales. So we could use inheritance to refactor the design into this:
UML for Salesperson inherits from Salaried.
          classDiagram
          class SalariedEmployee {
            -m_name: string
            -m_title: string
            -m_salary: double
            +calculatePay(): double
          }
          class HourlyEmployee {
            -m_name: string
            -m_title: string
            -m_hoursWorked: double
            -m_hourlyRate: double
            +calculatePay(): double
          }
          class Salesperson {
            -m_sales: double
            +calculatePay(): double
          }
          SalariedEmployee <|-- Salesperson
        
      
Figure 19.12.2. UML for Salesperson inherits from Salaried
We in Salesperson, we only need to write the new members, or the member functions that will be overridden. A Salesperson will need a m_sales variable and a new way to calculatePay(). Everything else can be inherited from SalariedEmployee.
There do not appear to be any easy cases of existing is-a relations. Salaried and Hourly employees have data in common, but it is not accurate to say that either one is-a the other. What is there in common? A m_name, m_title, and the ability to calculatePay(). So we could factor those out into some new common parent class. What describes both classes? How about β€œEmployee”?
Although we want a class Employee to represent common attributes and behaviors, we should never have someone who is just an Employee. They either need to be hourly or salaried. Without knowing which they are, we have no way to calculate their pay. So calculatePay() will be a pure virtual function in Employee, which will be an abstract class:
UML for SalariedEmployee and HourlyEmployee inheriting from Employee.
          classDiagram
          class SalariedEmployee {
            -m_salary : double
            +calculatePay() double
          }
          class HourlyEmployee {
            -m_hoursWorked : double
            -m_hourlyRate : double
            +calculatePay() double
          }
          class `*Employee*` {
            <<Abstract>>
            -m_name : string
            -m_title : string
            +calculatePay()* double
          }
          class Salesperson {
            -m_sales : double
            +calculatePay() double
          }
          SalariedEmployee <|-- Salesperson
          `*Employee*` <|-- SalariedEmployee
          `*Employee*` <|-- HourlyEmployee
        
      
Figure 19.12.3. UML for SalariedEmployee and HourlyEmployee inheriting from Employee

Checkpoint 19.12.1.

We have the UML shown below for Teacher and Student. We would like to make a new abstract class Person that they can both inherit from. Arrange the attributes into the class they most logically belong to.
UML for Student and Teacher classes. Student has m_major, m_name, m_age, and m_credits. Teacher has m_name, m_yearsExperience, and m_age.
        classDiagram
          class Student {
            -m_major : string
            -m_name : string
            -m_age : int
            -m_credits : int
          }
          class Teacher {
            -m_name : string
            -m_yearsExperience: int
            -m_age : int
          }
      
    
In your answer, place Person class first, then Teacher, then Student.

Checkpoint 19.12.2.

Based on the UML below. What is-a relationship seems likely?
UML for Foo and Bar classes. Foo has m_color, m_size, and m_label. Bar has m_size and m_label.
          classDiagram
            class Foo {
              -m_color: string
              -m_size : int
              -m_label : string
            }
            class Bar {
              -m_size : int
              -m_label : string
            }
        
      
  • Bar is-a Foo.
  • Correct. Foo has all the properties of Bar (and an additional one).
  • Foo is-a Bar.
  • Incorrect. Foo has properties that Bar does not.
  • There is no reasonable is-a to infer.
  • One of these looks like an extended version of the other...
You have attempted of activities on this page.