We have done unnecessary work to create Manager, which is
similar to (and really is a "kind of") Employee.

We can fix this using the OO concept of inheritance. If we
let a manager inherit from an employee, then it will get all the data
and functionality of an employee. We can then add any new data and
methods needed for a manager and redefine any methods that
differ for a manager.

Here, we show a new implementation of Manager that
inherits from Employee:

Excitingly, it has methods from Employee, like
getName(), that we did not declare or define in
Manager...

Remember, it inherited all the data and methods of an
Employee! Thus, we have reused our definition of
an employee to simplify defining a manager.

Class Hierarchy:

Since we now have one class that inherits from another, we have the
beginnings of a class hierarchy:

Employee
|
Manager

We say that Employee is the base class and
Manager is a derived class of Employee.

Note:
Alternatively, we may call Employee the superclass
and Manager the subclass.

If needed, this hierarchy could be extended to include more classes.

Adding a Supervisor

To add another type of employee, such as a supervisor, a new class
can be created. Two choices of where to place a Supervisor
class in the hierarchy are:

a) Employee b) Employee
| / \
Manager Manager Supervisor
|
Supervisor

A supervisor is a kind of manager.
The Supervisor class directly inherits from
Manager and indirectly inherits from
Employee.

A supervisor is just a special kind of employee.
Supervisordirectly inherits from
Employee.

Aside:
We can say that Supervisorinherits from
Employee when there is either a direct or indirect inheritance
relationship.

Which hierarchy would we choose?

If a supervisor is viewed as part of management, then choice a) is
probably your answer. Nonetheless, this is a decision not to be taken
lightly. How one designs the inheritance hierarchy greatly affects
what you can do with those classes later.