{"id":"inheritance-super-constructor","slug":"super-constructor","title":"Constructors and super(...)","text":"Step 2's classes had no constructors, so they got the default ones. Most classes have constructors that take values: a bank account needs an owner and a starting balance. How does a subclass hand values to its superclass's constructor?\n\n### super(...)\n\nA bank has plain accounts, and savings accounts that also earn interest at some rate. (Amounts are in whole dollars here, to keep the numbers short.)\n\n```java\npublic class Main {\n    public static void main(String[] args) {\n        SavingsAccount savings = new SavingsAccount(\"Mia\", 500, 3);\n        savings.deposit(100);\n        System.out.println(savings.getOwner());\n        System.out.println(savings.getBalance());\n        System.out.println(savings.getInterestPercent());\n    }\n}\n// ==== BankAccount.java ====\npublic class BankAccount {\n    private String owner;\n    private int balance;\n\n    public BankAccount(String owner, int balance) {\n        this.owner = owner;\n        this.balance = balance;\n    }\n\n    public String getOwner() {\n        return this.owner;\n    }\n\n    public int getBalance() {\n        return this.balance;\n    }\n\n    public void deposit(int amount) {\n        if (amount > 0) {\n            this.balance += amount;\n        }\n    }\n}\n// ==== SavingsAccount.java ====\npublic class SavingsAccount extends BankAccount {\n    private int interestPercent;\n\n    public SavingsAccount(String owner, int balance, int interestPercent) {\n        super(owner, balance);\n        this.interestPercent = interestPercent;\n    }\n\n    public int getInterestPercent() {\n        return this.interestPercent;\n    }\n}\n```\n\n```output\nMia\n600\n3\n```\n\n- A subclass doesn't inherit constructors. `SavingsAccount` writes its own, which takes all three values.\n- `super(owner, balance);` calls BankAccount's constructor with the owner and the balance. It sets up the BankAccount part of the object. It has to be BankAccount's constructor that does this: `owner` and `balance` are private to BankAccount, so SavingsAccount's code can't set them itself.\n- After it, the constructor sets up what SavingsAccount adds, the interest rate.\n- `super(...)` works like module 21's `this(...)`, which called another constructor of the same class. And the same rule holds: it must be the first statement of the constructor. In Java 21, the version this course runs, nothing may come before it.\n\n### The parent's part comes first\n\nA line printed in each constructor shows the order:\n\n```java\npublic class Main {\n    public static void main(String[] args) {\n        SavingsAccount savings = new SavingsAccount(\"Mia\", 500, 3);\n        BankAccount plain = new BankAccount(\"Leo\", 80);\n    }\n}\n// ==== BankAccount.java ====\npublic class BankAccount {\n    private String owner;\n    private int balance;\n\n    public BankAccount(String owner, int balance) {\n        this.owner = owner;\n        this.balance = balance;\n        System.out.println(\"Opening an account for \" + owner);\n    }\n}\n// ==== SavingsAccount.java ====\npublic class SavingsAccount extends BankAccount {\n    private int interestPercent;\n\n    public SavingsAccount(String owner, int balance, int interestPercent) {\n        super(owner, balance);\n        this.interestPercent = interestPercent;\n        System.out.println(\"Adding interest of \" + interestPercent + \"%\");\n    }\n}\n```\n\n```output\nOpening an account for Mia\nAdding interest of 3%\nOpening an account for Leo\n```\n\n`new SavingsAccount(...)` runs SavingsAccount's constructor. Its first line runs BankAccount's constructor all the way through, and only then does the rest of SavingsAccount's constructor run. An object is built from the top down: first the parent's part, then the child's. (BankAccount's constructor, in turn, first runs Object's, which does nothing you can see.)\n\n### When super(...) is missing\n\nIf a constructor doesn't start with `super(...)` or `this(...)`, Java puts `super();` there for you: a call to the superclass's constructor without parameters. That's what happened in step 2. Violin had no constructor at all, so it got the default one, which does nothing but call `super()`, and Instrument had the default constructor too.\n\nBankAccount has no constructor without parameters. So a SavingsAccount constructor that forgets `super(...)` doesn't compile:\n\n```java\npublic class Main {\n    public static void main(String[] args) {\n        SavingsAccount savings = new SavingsAccount(\"Mia\", 500, 3);\n    }\n}\n// ==== BankAccount.java ====\npublic class BankAccount {\n    private String owner;\n    private int balance;\n\n    public BankAccount(String owner, int balance) {\n        this.owner = owner;\n        this.balance = balance;\n    }\n}\n// ==== SavingsAccount.java ====\npublic class SavingsAccount extends BankAccount {\n    private int interestPercent;\n\n    public SavingsAccount(String owner, int balance, int interestPercent) {\n        this.interestPercent = interestPercent;\n    }\n}\n```\n\n```javac\nSavingsAccount.java:4: error: constructor BankAccount in class BankAccount cannot be applied to given types;\n    public SavingsAccount(String owner, int balance, int interestPercent) {\n                                                                          ^\n  required: String,int\n  found:    no arguments\n  reason: actual and formal argument lists differ in length\n1 error\n```\n\njavac points at the `{` that opens the constructor's body, where the hidden `super();` would be: BankAccount's constructor needs a String and an int, and it was given nothing. The fix is the line `super(owner, balance);`.\n","task":"The bank also has checking accounts, which may go below zero, down to an overdraft limit. `BankAccount.java` is ready. In `CheckingAccount.java`, write the class `CheckingAccount`, which extends BankAccount, with:\n\n- a constructor `CheckingAccount(String owner, int balance, int overdraftLimit)`, which hands the owner and the balance to BankAccount's constructor, and keeps the limit itself\n- `getOverdraftLimit()`, which returns the limit\n- `availableToSpend()`, which returns the balance plus the limit\n\nThe check runs:\n\n```java\nCheckingAccount account = new CheckingAccount(\"Ada\", 120, 200);\nSystem.out.println(account.getOwner() + \" \" + account.getBalance());\nSystem.out.println(account.availableToSpend());\naccount.deposit(30);\nSystem.out.println(account.availableToSpend());\n```\n\nand expects:\n\n```\nAda 120\n320\n350\n```\n","kind":"code","seed":"// ==== CheckingAccount.java ====\npublic class CheckingAccount {\n\n}\n\n// ==== BankAccount.java ====\npublic class BankAccount {\n    private String owner;\n    private int balance;\n\n    public BankAccount(String owner, int balance) {\n        this.owner = owner;\n        this.balance = balance;\n    }\n\n    public String getOwner() {\n        return this.owner;\n    }\n\n    public int getBalance() {\n        return this.balance;\n    }\n\n    public void deposit(int amount) {\n        if (amount > 0) {\n            this.balance += amount;\n        }\n    }\n}\n\n// ==== Main.java ====\npublic class Main {\n    public static void main(String[] args) {\n        CheckingAccount account = new CheckingAccount(\"Ada\", 120, 200);\n        System.out.println(account.getOwner() + \" \" + account.getBalance());\n        System.out.println(account.availableToSpend());\n        account.deposit(30);\n        System.out.println(account.availableToSpend());\n    }\n}\n","solution":"// ==== CheckingAccount.java ====\npublic class CheckingAccount extends BankAccount {\n    private int overdraftLimit;\n\n    public CheckingAccount(String owner, int balance, int overdraftLimit) {\n        super(owner, balance);\n        this.overdraftLimit = overdraftLimit;\n    }\n\n    public int getOverdraftLimit() {\n        return this.overdraftLimit;\n    }\n\n    public int availableToSpend() {\n        return this.getBalance() + this.overdraftLimit;\n    }\n}\n\n// ==== BankAccount.java ====\npublic class BankAccount {\n    private String owner;\n    private int balance;\n\n    public BankAccount(String owner, int balance) {\n        this.owner = owner;\n        this.balance = balance;\n    }\n\n    public String getOwner() {\n        return this.owner;\n    }\n\n    public int getBalance() {\n        return this.balance;\n    }\n\n    public void deposit(int amount) {\n        if (amount > 0) {\n            this.balance += amount;\n        }\n    }\n}\n\n// ==== Main.java ====\npublic class Main {\n    public static void main(String[] args) {\n        CheckingAccount account = new CheckingAccount(\"Ada\", 120, 200);\n        System.out.println(account.getOwner() + \" \" + account.getBalance());\n        System.out.println(account.availableToSpend());\n        account.deposit(30);\n        System.out.println(account.availableToSpend());\n    }\n}\n","hints":["The class starts `public class CheckingAccount extends BankAccount {` and has one variable of its own, the overdraft limit. The constructor's first line is `super(owner, balance);`.","The balance is private to BankAccount, so `availableToSpend()` gets it with the inherited `this.getBalance()`, and returns that plus `this.overdraftLimit`."],"tests":[{"name":"Test 1","stdin":"","call":"CheckingAccount account = new CheckingAccount(\"Ada\", 120, 200);\nSystem.out.println(account.getOwner() + \" \" + account.getBalance());\nSystem.out.println(account.availableToSpend());\naccount.deposit(30);\nSystem.out.println(account.availableToSpend());\n","expect":"Ada 120\n320\n350","hidden":false},{"name":"Test 2","stdin":"","call":"CheckingAccount account = new CheckingAccount(\"Ben\", 0, 50);\nSystem.out.println(account.getOwner() + \" \" + account.getBalance() + \" \" + account.getOverdraftLimit());\nSystem.out.println(account.availableToSpend());\naccount.deposit(-10);\naccount.deposit(5);\nSystem.out.println(account.availableToSpend() + \" \" + account.getBalance());\n","expect":"Ben 0 50\n50\n55 5","hidden":true},{"name":"Test 3","stdin":"","call":"CheckingAccount first = new CheckingAccount(\"Cy\", 300, 0);\nCheckingAccount second = new CheckingAccount(\"Dee\", 10, 1000);\nSystem.out.println(first.availableToSpend() + \" \" + second.availableToSpend());\n","expect":"300 1010","hidden":true}],"require":[{"pattern":"\\bclass\\s+CheckingAccount\\s+extends\\s+BankAccount\\b","message":"Write the header as `public class CheckingAccount extends BankAccount`."},{"pattern":"\\bsuper\\s*\\(","message":"Hand the owner and the balance to BankAccount's constructor with `super(owner, balance);`."}],"forbid":[],"more":[{"task":"A courier registers every shipment, and a letter is a shipment. Both constructors print a line. What does this program print?\n","kind":"predict","seed":"public class Main {\n    public static void main(String[] args) {\n        Letter letter = new Letter(17, true);\n        System.out.println(letter.getCode());\n        Shipment box = new Shipment(\"S-2\");\n    }\n}\n// ==== Shipment.java ====\npublic class Shipment {\n    private String code;\n\n    public Shipment(String code) {\n        this.code = code;\n        System.out.println(\"Shipment \" + code + \" registered\");\n    }\n\n    public String getCode() {\n        return this.code;\n    }\n}\n// ==== Letter.java ====\npublic class Letter extends Shipment {\n    private boolean express;\n\n    public Letter(int number, boolean express) {\n        super(\"L-\" + number);\n        this.express = express;\n        System.out.println(\"Letter, express: \" + express);\n    }\n}\n","solution":"public class Main {\n    public static void main(String[] args) {\n        Letter letter = new Letter(17, true);\n        System.out.println(letter.getCode());\n        Shipment box = new Shipment(\"S-2\");\n    }\n}\n// ==== Shipment.java ====\npublic class Shipment {\n    private String code;\n\n    public Shipment(String code) {\n        this.code = code;\n        System.out.println(\"Shipment \" + code + \" registered\");\n    }\n\n    public String getCode() {\n        return this.code;\n    }\n}\n// ==== Letter.java ====\npublic class Letter extends Shipment {\n    private boolean express;\n\n    public Letter(int number, boolean express) {\n        super(\"L-\" + number);\n        this.express = express;\n        System.out.println(\"Letter, express: \" + express);\n    }\n}\n","hints":["`new Letter(...)` runs Letter's constructor, whose first line runs Shipment's constructor to the end. Shipment's line is printed first.","Letter hands Shipment the code `\"L-\" + number`, which is `L-17`, and that's the code `getCode()` returns. The plain Shipment runs only Shipment's constructor."],"tests":[{"name":"Output","stdin":"","expect":"Shipment L-17 registered\nLetter, express: true\nL-17\nShipment S-2 registered","hidden":false}],"require":[],"forbid":[],"lines":["Shipment L-17 registered","Letter, express: true","L-17","Shipment S-2 registered"]},{"task":"A museum's sculptures are exhibits too, with a material of their own. Fill in the blank, so that Sculpture's constructor hands the name and the year to Exhibit's constructor.\n","kind":"fill","seed":"public class Main {\n    public static void main(String[] args) {\n        Sculpture lion = new Sculpture(\"Sleeping lion\", 1860, \"marble\");\n        System.out.println(lion.getName() + \", \" + lion.getYear() + \", \" + lion.getMaterial());\n    }\n}\n// ==== Exhibit.java ====\npublic class Exhibit {\n    private String name;\n    private int year;\n\n    public Exhibit(String name, int year) {\n        this.name = name;\n        this.year = year;\n    }\n\n    public String getName() {\n        return this.name;\n    }\n\n    public int getYear() {\n        return this.year;\n    }\n}\n// ==== Sculpture.java ====\npublic class Sculpture extends Exhibit {\n    private String material;\n\n    public Sculpture(String name, int year, String material) {\n        [[super]](name, year);\n        this.material = material;\n    }\n\n    public String getMaterial() {\n        return this.material;\n    }\n}\n","solution":"public class Main {\n    public static void main(String[] args) {\n        Sculpture lion = new Sculpture(\"Sleeping lion\", 1860, \"marble\");\n        System.out.println(lion.getName() + \", \" + lion.getYear() + \", \" + lion.getMaterial());\n    }\n}\n// ==== Exhibit.java ====\npublic class Exhibit {\n    private String name;\n    private int year;\n\n    public Exhibit(String name, int year) {\n        this.name = name;\n        this.year = year;\n    }\n\n    public String getName() {\n        return this.name;\n    }\n\n    public int getYear() {\n        return this.year;\n    }\n}\n// ==== Sculpture.java ====\npublic class Sculpture extends Exhibit {\n    private String material;\n\n    public Sculpture(String name, int year, String material) {\n        super(name, year);\n        this.material = material;\n    }\n\n    public String getMaterial() {\n        return this.material;\n    }\n}\n","hints":["Sculpture's constructor must first call its superclass's constructor, with the name and the year.","The word for the superclass's constructor is `super`: `super(name, year);`."],"tests":[{"name":"Output","stdin":"","expect":"Sleeping lion, 1860, marble","hidden":false}],"require":[],"forbid":[]}]}