Start learning free

LESSON 558 OF 569 · OBJECT-ORIENTED PROGRAMMING - CHALLENGES

Employees and Managers in Java: Inheritance and super

Practice O(1) Read the full explanation

A company pays every employee a salary. A manager is an employee too, but earns a bonus on top of the salary. Write the two classes so that a manager reuses everything an employee has, and changes only how its pay is worked out.

Implement the class Employee:

  • Employee(name, salary) creates an employee. The name and the salary are private to Employee.
  • pay() returns the salary.
  • describe() returns the text <name> earns <pay>, where the amount is what pay() returns, for example Ana earns 3000.

and the class Manager, which inherits from Employee:

  • Manager(name, salary, bonus) lets the parent's constructor store the name and the salary, and stores the bonus itself, private to Manager.
  • pay() returns the parent's pay() plus the bonus. Call the parent's version, as in the lesson Calling the Parent Method: the salary is private to Employee, and the parent's pay() is what knows how an employee is paid.
  • describe() is not written again: Manager inherits it unchanged. Because describe() calls pay(), a manager's description shows the manager's pay, bonus included.

The input is a list of people, one per line: employee name salary or manager name salary bonus. For each line, the code that tests your classes creates that object and prints what its describe() returns, on a line of its own. The starter code spells these names the way your language does.

 

Example 1:

Input:
    employee Ana 3000
    manager Bob 4000 1000
Output:
    Ana earns 3000
    Bob earns 5000
Explanation:
Ana's pay is her salary. Bob's pay is the parent's pay, his salary 4000, plus his bonus 1000.
Bob's describe() is Employee's describe(), but the pay() it calls is Manager's.

Example 2:

Input:
    manager Cleo 5000 0
    employee Dan 5000
Output:
    Cleo earns 5000
    Dan earns 5000
Explanation: A manager whose bonus is 0 earns exactly the salary, like an employee.

Example 3:

Input:
    manager Eve 7000 2500
    employee Finn 2800
    employee Gus 3100
    manager Hana 6000 500
Output:
    Eve earns 9500
    Finn earns 2800
    Gus earns 3100
    Hana earns 6500
Explanation: Employees and managers come in any order, and each object keeps its own name and numbers.

 

Constraints:

  • 0 <= salary <= 106
  • 0 <= bonus <= 106
  • A name is one word of 1 to 20 English letters. Two people may have the same name.
  • At most 100 people per test case.
STEP 1 OF 9
    Ctrl + Enter to check

    JAVA · OBJECT-ORIENTED PROGRAMMING - CHALLENGES

    Employees And Managers in Java, explained

    Problem overview

    A company pays every employee a salary. A manager is an employee too, but earns a bonus on top of the salary. The task is to write two classes so that Manager reuses everything Employee has and changes only how the pay is worked out.

    • Employee(name, salary) stores the name and the salary, both private.
    • pay() returns the salary.
    • describe() returns text such as Ana earns 3000, using the value of pay().
    • Manager(name, salary, bonus) extends Employee, passes the name and salary to the parent, and stores the bonus itself.
    • A manager's pay() is the parent's pay() plus the bonus. describe() is not written again.

    An employee called Ana with a salary of 3000 earns 3000. A manager called Bob with a salary of 4000 and a bonus of 1000 earns 5000, and his description says so.

    Approach: override one method, inherit the rest

    Inheritance means a subclass starts with everything its parent has. Manager extends Employee, so a manager already has a name, a salary, pay and describe. The only difference is the pay rule, so Manager overrides pay and nothing else.

    The trick is in describe. It calls pay() instead of reading the salary. When describe runs on a manager, the call pay() goes to the manager's version, so the bonus appears in the text without a second describe. Java picks the method by the real type of the object, not by the type of the variable that holds it.

    The salary is private to Employee, so Manager can't read it. That is why Manager.pay calls super.pay(): the parent's version knows how an employee is paid.

    Step by step

    1. Declare private String name and private int salary in Employee. Private means not even Manager can use them directly.
    2. The constructor stores both with this.name = name and this.salary = salary.
    3. pay returns salary.
    4. describe returns name + " earns " + pay(). Adding an int to a String with + turns the number into text. Calling pay() rather than reading salary is what makes managers work.
    5. Write Manager extends Employee with its own private int bonus.
    6. Start the constructor with super(name, salary). It runs Employee's constructor, the only code that can fill in the private fields. Java requires it to be the first line.
    7. Store the bonus with this.bonus = bonus.
    8. Override pay: return super.pay() + bonus.

    The solution in Java

    class Employee {
        private String name;
        private int salary;
        public Employee(String name, int salary) {
            this.name = name;
            this.salary = salary;
        }
        public int pay() {
            return salary;
        }
        public String describe() {
            return name + " earns " + pay();
        }
    }
    class Manager extends Employee {
        private int bonus;
        public Manager(String name, int salary, int bonus) {
            super(name, salary);
            this.bonus = bonus;
        }
        @Override
        public int pay() {
            return super.pay() + bonus;
        }
    }
    

    Java details:

    • @Override asks the compiler to check that the method really overrides one from the parent. A typo such as Pay would then be an error instead of a silent new method.
    • super.pay() calls the parent's version. Writing just pay() inside Manager.pay would call the same method again, forever. The program would end with a StackOverflowError.
    • If Manager's constructor didn't call super(...), Java would look for an Employee constructor with no parameters. There is none, so it wouldn't compile.

    The classes divide the work cleanly. Employee knows how to store a person and how to write the sentence. Manager knows only what makes a manager different: one extra number and one changed rule. Anything else about managers, such as the name and the sentence, comes from the parent.

    Using the classes

    Employee[] staff = {
        new Employee("Ana", 3000),
        new Manager("Bob", 4000, 1000),
        new Manager("Cleo", 5000, 0),
        new Manager("Eve", 7000, 2500),
        new Employee("Finn", 2800)
    };
    for (Employee e : staff) {
        System.out.println(e.describe());
    }
    

    prints:

    Ana earns 3000
    Bob earns 5000
    Cleo earns 5000
    Eve earns 9500
    Finn earns 2800
    

    The array holds both kinds of object as Employee, and each call to describe() still uses the right pay(). A manager with a bonus of 0, such as Cleo, earns exactly her salary.

    How one describe call is worked out

    For Bob, created as new Manager("Bob", 4000, 1000), the call describe() goes through these steps:

    1. Manager has no describe, so Java uses the one it inherited from Employee.
    2. That method builds name + " earns " + pay(). The object is a Manager, so pay() runs Manager's version.
    3. That version calls super.pay(), which is Employee's version and returns the salary, 4000, and then adds the bonus, 1000.
    4. The text becomes Bob earns 5000.

    In the array above, the variable e has the type Employee for every element, yet the call that runs depends on the object that e refers to at that moment. This is called polymorphism, and it is why describe needs no changes for new kinds of employees: a class that overrides pay gets a correct description for free.

    Common mistakes

    • Reading salary in describe. Managers would show their salary without the bonus.
    • Writing describe again in Manager. It works, but it copies code, and the point of inheritance is to avoid that.
    • Calling pay() instead of super.pay() inside the override. The method calls itself and never returns.
    • Making the fields public to avoid super. It compiles, but it gives up the protection private provides.
    • Not passing every parent argument to super. The name and the salary both go there; only the bonus is stored in Manager.

    Complexity

    Each method runs in O(1) time, apart from building the text in describe, which is proportional to the length of the name, at most 20 letters here. Each object stores a name and one or two integers.

    Keep going with Java500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free