{"id":"inheritance-extends","slug":"extends","title":"extends: a class built on another","text":"A music school lends instruments to its students and keeps track of how long each one has been played. Every instrument needs that, whatever kind it is. Violins need something more: now and then a string breaks and gets changed, and the school counts those too.\n\nYou could copy the code for the minutes into a Violin class, a Drum class and every other kind. With inheritance you write it once, in a class `Instrument`, and `Violin` **extends** it:\n\n```java\npublic class Main {\n    public static void main(String[] args) {\n        Violin violin = new Violin();\n        violin.practice(30);\n        violin.practice(45);\n        violin.changeString();\n        violin.changeString();\n        System.out.println(violin.getMinutesPlayed());\n        System.out.println(violin.getStringsChanged());\n        System.out.println(violin.report());\n\n        Instrument shaker = new Instrument();\n        shaker.practice(10);\n        System.out.println(shaker.getMinutesPlayed());\n    }\n}\n// ==== Instrument.java ====\npublic class Instrument {\n    private int minutesPlayed;\n\n    public void practice(int minutes) {\n        this.minutesPlayed += minutes;\n    }\n\n    public int getMinutesPlayed() {\n        return this.minutesPlayed;\n    }\n}\n// ==== Violin.java ====\npublic class Violin extends Instrument {\n    private int stringsChanged;\n\n    public void changeString() {\n        this.stringsChanged++;\n    }\n\n    public int getStringsChanged() {\n        return this.stringsChanged;\n    }\n\n    public String report() {\n        return this.getMinutesPlayed() + \" minutes, \" + this.stringsChanged + \" strings changed\";\n    }\n}\n```\n\n```output\n75\n2\n75 minutes, 2 strings changed\n10\n```\n\n- `public class Violin extends Instrument` makes Violin a **subclass** of Instrument, and Instrument the **superclass** of Violin. You'll also hear child class and parent class.\n- A Violin object has everything an Instrument has: the variable `minutesPlayed` and the methods `practice` and `getMinutesPlayed`. On top of that it has what Violin adds: `stringsChanged`, `changeString`, `getStringsChanged` and `report`. So `violin.practice(30)` works, although Violin's code never mentions `practice`.\n- Violin's own methods can call the methods it inherits, just like its own: `report` calls `this.getMinutesPlayed()`.\n- `report` can't write `this.minutesPlayed`, though. That variable is `private` to Instrument, so only Instrument's code can use it by name. Every Violin object has it, and `practice` changes it, but Violin's code reaches it only through Instrument's public methods. Step 5 is about this.\n- Neither class has a constructor, so each gets the default constructor from module 17, and the numbers start at 0. The next step adds constructors that take values.\n\n### A plain Instrument has only Instrument's methods\n\n`shaker` is an Instrument, not a Violin. Inheritance goes one way: the subclass gets the superclass's methods, never the other way around.\n\n```java\npublic class Main {\n    public static void main(String[] args) {\n        Instrument shaker = new Instrument();\n        shaker.changeString();\n    }\n}\n// ==== Instrument.java ====\npublic class Instrument {\n    private int minutesPlayed;\n\n    public void practice(int minutes) {\n        this.minutesPlayed += minutes;\n    }\n\n    public int getMinutesPlayed() {\n        return this.minutesPlayed;\n    }\n}\n```\n\n```javac\nMain.java:4: error: cannot find symbol\n        shaker.changeString();\n              ^\n  symbol:   method changeString()\n  location: variable shaker of type Instrument\n1 error\n```\n\n### One superclass, many subclasses\n\nA class can extend only one class. But one class can have many subclasses: the school's `Drum` can extend Instrument too, and count its broken drumsticks:\n\n```java\npublic class Drum extends Instrument {\n    private int sticksBroken;\n\n    public void breakStick() {\n        this.sticksBroken++;\n    }\n}\n```\n\nA Drum and a Violin share Instrument's part, and each adds its own. A Drum has no `changeString`, and a Violin has no `breakStick`.\n\nInheritance also goes up more than one level. Instrument doesn't say what it extends, so it extends Object (step 1). So a Violin has Object's methods as well: `violin.getClass().getName()` gives `Violin`.\n","task":"The school also lends pianos, and a piano needs tuning after every 60 minutes of playing. `Instrument.java` is ready. In `Piano.java`, write the class `Piano`, which extends Instrument and adds two methods:\n\n- `tune()`, which remembers how many minutes the piano had been played when it was tuned\n- `needsTuning()`, which returns `true` when the piano has been played for at least 60 minutes since it was last tuned. A new piano counts as just tuned.\n\nUse the inherited `getMinutesPlayed()`. The check runs:\n\n```java\nPiano piano = new Piano();\npiano.practice(45);\nSystem.out.println(piano.needsTuning());\npiano.practice(30);\nSystem.out.println(piano.needsTuning());\npiano.tune();\nSystem.out.println(piano.needsTuning());\nSystem.out.println(piano.getMinutesPlayed());\n```\n\nand expects:\n\n```\nfalse\ntrue\nfalse\n75\n```\n","kind":"code","seed":"// ==== Piano.java ====\npublic class Piano {\n\n}\n\n// ==== Instrument.java ====\npublic class Instrument {\n    private int minutesPlayed;\n\n    public void practice(int minutes) {\n        this.minutesPlayed += minutes;\n    }\n\n    public int getMinutesPlayed() {\n        return this.minutesPlayed;\n    }\n}\n\n// ==== Main.java ====\npublic class Main {\n    public static void main(String[] args) {\n        Piano piano = new Piano();\n        piano.practice(45);\n        System.out.println(piano.needsTuning());\n        piano.practice(30);\n        System.out.println(piano.needsTuning());\n        piano.tune();\n        System.out.println(piano.needsTuning());\n        System.out.println(piano.getMinutesPlayed());\n    }\n}\n","solution":"// ==== Piano.java ====\npublic class Piano extends Instrument {\n    private int minutesAtTuning;\n\n    public void tune() {\n        this.minutesAtTuning = this.getMinutesPlayed();\n    }\n\n    public boolean needsTuning() {\n        return this.getMinutesPlayed() - this.minutesAtTuning >= 60;\n    }\n}\n\n// ==== Instrument.java ====\npublic class Instrument {\n    private int minutesPlayed;\n\n    public void practice(int minutes) {\n        this.minutesPlayed += minutes;\n    }\n\n    public int getMinutesPlayed() {\n        return this.minutesPlayed;\n    }\n}\n\n// ==== Main.java ====\npublic class Main {\n    public static void main(String[] args) {\n        Piano piano = new Piano();\n        piano.practice(45);\n        System.out.println(piano.needsTuning());\n        piano.practice(30);\n        System.out.println(piano.needsTuning());\n        piano.tune();\n        System.out.println(piano.needsTuning());\n        System.out.println(piano.getMinutesPlayed());\n    }\n}\n","hints":["Start with `public class Piano extends Instrument {`. Piano needs one variable of its own: the minutes played at the last tuning, which starts at 0 like any int instance variable.","`tune()` stores `this.getMinutesPlayed()` in that variable. `needsTuning()` returns `this.getMinutesPlayed() - this.minutesAtTuning >= 60`."],"tests":[{"name":"Test 1","stdin":"","call":"Piano piano = new Piano();\npiano.practice(45);\nSystem.out.println(piano.needsTuning());\npiano.practice(30);\nSystem.out.println(piano.needsTuning());\npiano.tune();\nSystem.out.println(piano.needsTuning());\nSystem.out.println(piano.getMinutesPlayed());\n","expect":"false\ntrue\nfalse\n75","hidden":false},{"name":"Test 2","stdin":"","call":"Piano piano = new Piano();\nSystem.out.println(piano.needsTuning());\npiano.practice(60);\nSystem.out.println(piano.needsTuning());\npiano.tune();\npiano.practice(59);\nSystem.out.println(piano.needsTuning() + \" \" + piano.getMinutesPlayed());\npiano.practice(1);\nSystem.out.println(piano.needsTuning());\n","expect":"false\ntrue\nfalse 119\ntrue","hidden":true},{"name":"Test 3","stdin":"","call":"Piano first = new Piano();\nPiano second = new Piano();\nfirst.practice(100);\nsecond.practice(20);\nfirst.tune();\nSystem.out.println(first.needsTuning() + \" \" + second.needsTuning());\nsecond.practice(50);\nSystem.out.println(second.needsTuning() + \" \" + first.getMinutesPlayed());\n","expect":"false false\ntrue 100","hidden":true}],"require":[{"pattern":"\\bclass\\s+Piano\\s+extends\\s+Instrument\\b","message":"Write the header as `public class Piano extends Instrument`, so that a piano gets Instrument's methods."}],"forbid":[],"more":[{"task":"`Drum` and `Violin` both extend `Instrument`, which has a `toString` of its own. What does this program print?\n","kind":"predict","seed":"public class Main {\n    public static void main(String[] args) {\n        Drum drum = new Drum();\n        Drum spare = new Drum();\n        drum.practice(20);\n        drum.practice(25);\n        spare.practice(5);\n        drum.breakStick();\n        System.out.println(drum);\n        System.out.println(spare.getMinutesPlayed() + \" \" + spare.getSticksBroken());\n        System.out.println(drum.getClass().getName());\n    }\n}\n// ==== Instrument.java ====\npublic class Instrument {\n    private int minutesPlayed;\n\n    public void practice(int minutes) {\n        this.minutesPlayed += minutes;\n    }\n\n    public int getMinutesPlayed() {\n        return this.minutesPlayed;\n    }\n\n    public String toString() {\n        return \"played for \" + this.minutesPlayed + \" minutes\";\n    }\n}\n// ==== Drum.java ====\npublic class Drum extends Instrument {\n    private int sticksBroken;\n\n    public void breakStick() {\n        this.sticksBroken++;\n    }\n\n    public int getSticksBroken() {\n        return this.sticksBroken;\n    }\n}\n","solution":"public class Main {\n    public static void main(String[] args) {\n        Drum drum = new Drum();\n        Drum spare = new Drum();\n        drum.practice(20);\n        drum.practice(25);\n        spare.practice(5);\n        drum.breakStick();\n        System.out.println(drum);\n        System.out.println(spare.getMinutesPlayed() + \" \" + spare.getSticksBroken());\n        System.out.println(drum.getClass().getName());\n    }\n}\n// ==== Instrument.java ====\npublic class Instrument {\n    private int minutesPlayed;\n\n    public void practice(int minutes) {\n        this.minutesPlayed += minutes;\n    }\n\n    public int getMinutesPlayed() {\n        return this.minutesPlayed;\n    }\n\n    public String toString() {\n        return \"played for \" + this.minutesPlayed + \" minutes\";\n    }\n}\n// ==== Drum.java ====\npublic class Drum extends Instrument {\n    private int sticksBroken;\n\n    public void breakStick() {\n        this.sticksBroken++;\n    }\n\n    public int getSticksBroken() {\n        return this.sticksBroken;\n    }\n}\n","hints":["Drum has no `toString` of its own, so it inherits Instrument's, and `println(drum)` uses that one, not Object's.","Each Drum object has its own minutes and its own broken sticks: `spare` was played only once, and it broke nothing. `getClass().getName()` gives the class the object was made from."],"tests":[{"name":"Output","stdin":"","expect":"played for 45 minutes\n5 0\nDrum","hidden":false}],"require":[],"forbid":[],"lines":["played for 45 minutes","5 0","Drum"]},{"task":"The school's trumpets and flutes were written before anyone thought of inheritance, so `Trumpet` and `Flute` both have the same code for the minutes played. Move that code into `Instrument`: its variable `minutesPlayed` and its methods `practice` and `getMinutesPlayed`. Then make Trumpet and Flute extend Instrument, and keep only their own things in them: the valve oilings in Trumpet, the cleanings in Flute. `practice` and `getMinutesPlayed` should be written only once, in Instrument. The program prints:\n\n```\nTrumpet: 25 minutes, oiled 2 times\nFlute: 55 minutes, cleaned 2 times\n```\n","kind":"code","seed":"// ==== Instrument.java ====\npublic class Instrument {\n\n}\n\n// ==== Trumpet.java ====\npublic class Trumpet {\n    private int minutesPlayed;\n    private int valveOilings;\n\n    public void practice(int minutes) {\n        this.minutesPlayed += minutes;\n    }\n\n    public int getMinutesPlayed() {\n        return this.minutesPlayed;\n    }\n\n    public void oilValves() {\n        this.valveOilings++;\n    }\n\n    public int getValveOilings() {\n        return this.valveOilings;\n    }\n}\n\n// ==== Flute.java ====\npublic class Flute {\n    private int minutesPlayed;\n    private int cleanings;\n\n    public void practice(int minutes) {\n        this.minutesPlayed += minutes;\n    }\n\n    public int getMinutesPlayed() {\n        return this.minutesPlayed;\n    }\n\n    public void clean() {\n        this.cleanings++;\n    }\n\n    public int getCleanings() {\n        return this.cleanings;\n    }\n}\n\n// ==== Main.java ====\npublic class Main {\n    public static void main(String[] args) {\n        Trumpet trumpet = new Trumpet();\n        trumpet.practice(25);\n        trumpet.oilValves();\n        trumpet.oilValves();\n        Flute flute = new Flute();\n        flute.practice(40);\n        flute.practice(15);\n        flute.clean();\n        flute.clean();\n        System.out.println(\"Trumpet: \" + trumpet.getMinutesPlayed() + \" minutes, oiled \" + trumpet.getValveOilings() + \" times\");\n        System.out.println(\"Flute: \" + flute.getMinutesPlayed() + \" minutes, cleaned \" + flute.getCleanings() + \" times\");\n    }\n}\n","solution":"// ==== Instrument.java ====\npublic class Instrument {\n    private int minutesPlayed;\n\n    public void practice(int minutes) {\n        this.minutesPlayed += minutes;\n    }\n\n    public int getMinutesPlayed() {\n        return this.minutesPlayed;\n    }\n}\n\n// ==== Trumpet.java ====\npublic class Trumpet extends Instrument {\n    private int valveOilings;\n\n    public void oilValves() {\n        this.valveOilings++;\n    }\n\n    public int getValveOilings() {\n        return this.valveOilings;\n    }\n}\n\n// ==== Flute.java ====\npublic class Flute extends Instrument {\n    private int cleanings;\n\n    public void clean() {\n        this.cleanings++;\n    }\n\n    public int getCleanings() {\n        return this.cleanings;\n    }\n}\n\n// ==== Main.java ====\npublic class Main {\n    public static void main(String[] args) {\n        Trumpet trumpet = new Trumpet();\n        trumpet.practice(25);\n        trumpet.oilValves();\n        trumpet.oilValves();\n        Flute flute = new Flute();\n        flute.practice(40);\n        flute.practice(15);\n        flute.clean();\n        flute.clean();\n        System.out.println(\"Trumpet: \" + trumpet.getMinutesPlayed() + \" minutes, oiled \" + trumpet.getValveOilings() + \" times\");\n        System.out.println(\"Flute: \" + flute.getMinutesPlayed() + \" minutes, cleaned \" + flute.getCleanings() + \" times\");\n    }\n}\n","hints":["Cut `minutesPlayed`, `practice` and `getMinutesPlayed` out of Trumpet, paste them into Instrument, and delete them from Flute too.","Then change the headers to `public class Trumpet extends Instrument` and `public class Flute extends Instrument`. Main doesn't change: trumpets and flutes still have `practice`, now inherited."],"tests":[{"name":"The program's output","stdin":"","expect":"Trumpet: 25 minutes, oiled 2 times\nFlute: 55 minutes, cleaned 2 times","hidden":false},{"name":"Test 2","stdin":"","call":"Instrument bell = new Instrument();\nbell.practice(5);\nbell.practice(7);\nSystem.out.println(bell.getMinutesPlayed());\nTrumpet trumpet = new Trumpet();\nSystem.out.println(trumpet.getMinutesPlayed() + \" \" + trumpet.getValveOilings());\n","expect":"12\n0 0","hidden":true},{"name":"Test 3","stdin":"","call":"Flute first = new Flute();\nFlute second = new Flute();\nfirst.practice(10);\nsecond.practice(30);\nsecond.clean();\nSystem.out.println(first.getMinutesPlayed() + \" \" + first.getCleanings());\nSystem.out.println(second.getMinutesPlayed() + \" \" + second.getCleanings());\n","expect":"10 0\n30 1","hidden":true}],"require":[{"pattern":"\\bclass\\s+Trumpet\\s+extends\\s+Instrument\\b","message":"Make Trumpet extend Instrument: `public class Trumpet extends Instrument`."},{"pattern":"\\bclass\\s+Flute\\s+extends\\s+Instrument\\b","message":"Make Flute extend Instrument: `public class Flute extends Instrument`."},{"pattern":"\\bvoid\\s+practice\\s*\\(","max":1,"message":"Write `practice` only once, in Instrument. Trumpet and Flute inherit it."},{"pattern":"\\bint\\s+getMinutesPlayed\\s*\\(","max":1,"message":"Write `getMinutesPlayed` only once, in Instrument. Trumpet and Flute inherit it."}],"forbid":[]}]}