Start learning free

LESSON 562 OF 573 · OBJECT-ORIENTED PROGRAMMING - CHALLENGES

Employees and Managers in Scala: 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 3
    Ctrl + Enter to check

    SCALA · OBJECT-ORIENTED PROGRAMMING - CHALLENGES

    Employees And Managers in Scala, explained

    Problem overview

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

    • Employee(name, salary) keeps both privately. pay() returns the salary, and describe() returns the text <name> earns <pay>.
    • Manager(name, salary, bonus) inherits from Employee and stores the bonus privately. Its pay() returns the parent's pay plus the bonus. It does not write describe() again.

    Ana, an employee with salary 3000, is described as Ana earns 3000. Bob, a manager with salary 4000 and bonus 1000, is described as Bob earns 5000.

    Approach: override one method, inherit the rest

    The only thing that differs between the two is the pay. So Manager overrides pay() and inherits everything else. describe() is written once in Employee, and it builds its text from pay(), not from the salary field. When it runs on a manager, the call to pay() goes to the manager's version, so the bonus shows up without a second describe.

    In the manager's pay(), the salary is private to Employee, so the manager can't read it. It asks the parent instead, with super.pay(), which runs Employee's version. That way the salary rule stays in the code that owns it.

    Step by step

    1. Employee's pay returns salary. The header's private val already made name and salary private fields.
    2. Employee's describe returns an s"..." string: $name, then earns , then ${pay()}. Calling pay() rather than reading salary is what makes the text right for managers.
    3. Manager's pay overrides the parent's and returns super.pay() + bonus. The header extends Employee(name, salary) hands the name and salary to the parent's constructor, and private val bonus keeps the bonus.

    The solution in Scala

    class Employee(private val name: String, private val salary: Int) {
        def pay(): Int = {
            return salary
        }
    
        def describe(): String = {
            return s"$name earns ${pay()}"
        }
    }
    
    class Manager(name: String, salary: Int, private val bonus: Int) extends Employee(name, salary) {
        override def pay(): Int = {
            return super.pay() + bonus
        }
    }
    

    Scala details:

    • extends Employee(name, salary) calls the parent's constructor. In Manager's header, name and salary have no val, so they are only parameters passed up, not new fields.
    • override is required. A method that replaces an inherited one must be marked override, which also lets the compiler catch a misspelled name.
    • super.pay() calls the parent's version. Writing plain pay() in the manager would call the manager's own method again and again, until the program fails with a stack overflow.
    • String interpolation. In s"$name earns ${pay()}", $name inserts a value and ${...} inserts the value of any expression, here a method call.

    Using the classes

    val e = new Employee("Ana", 3000)
    val mg = new Manager("Bob", 4000, 1000)
    println(e.describe())
    println(mg.describe())
    println(mg.pay())
    val staff: List[Employee] = List(e, mg, new Manager("Cleo", 5000, 0))
    for (s <- staff) println(s.describe())

    It prints:

    Ana earns 3000
    Bob earns 5000
    5000
    Ana earns 3000
    Bob earns 5000
    Cleo earns 5000

    A Manager can be used wherever an Employee is expected. The list is typed List[Employee] and holds both kinds, and each element's describe() uses its own pay(). Cleo, whose bonus is 0, earns exactly her salary.

    Complexity

    Each method does a constant amount of work: one addition, or building a short string. Both are O(1) in the sizes of the numbers involved.

    Common mistakes

    • Calling pay() inside pay(). It recurses forever. Use super.pay().
    • Reading salary in describe. Managers would be described without their bonus.
    • Writing describe() again in Manager. It isn't needed, and a copy can drift out of step with the original.
    • Adding val to the manager's name and salary parameters. That declares new fields that hide the parent's private ones and duplicate them.
    • Leaving out override. The compiler rejects the method.
    Keep going with Scala500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free