{"id":"class-diagrams-methods","slug":"methods","title":"Constructors and methods in a box","text":"A box has room for more than fields. Under a second line come the class's constructors and methods. Here's the recycling center's bin with them:\n\n\n<figure class=\"uml\"><div class=\"uml-scroll\" tabindex=\"0\" role=\"group\" aria-label=\"Class diagram of Bin\">\n<svg class=\"uml-svg\" viewBox=\"0 0 295 180\" width=\"295\" height=\"180\" style=\"width:18.44rem;min-width:16.91rem;aspect-ratio:295/180\" font-size=\"12\" aria-hidden=\"true\" focusable=\"false\"><rect class=\"u-bg\" fill=\"none\" x=\"6\" y=\"6\" width=\"283\" height=\"168\"/><rect class=\"u-head\" fill=\"none\" x=\"6\" y=\"6\" width=\"283\" height=\"24\"/><text x=\"147.5\" y=\"22\" text-anchor=\"middle\" class=\"u-name\">Bin</text><text x=\"14\" y=\"46\">-material: String</text><text x=\"14\" y=\"62\">-capacity: int</text><text x=\"14\" y=\"78\">-load: int</text><text x=\"14\" y=\"102\">+Bin(material: String, capacity: int)</text><text x=\"14\" y=\"118\">+getMaterial(): String</text><text x=\"14\" y=\"134\">+add(kilos: int): boolean</text><text x=\"14\" y=\"150\">+empty(): void</text><text x=\"14\" y=\"166\">+toString(): String</text><path class=\"u-sep\" fill=\"none\" d=\"M6 30h283M6 86h283\"/><rect class=\"u-frame\" fill=\"none\" x=\"6\" y=\"6\" width=\"283\" height=\"168\"/></svg>\n</div><details class=\"uml-text\"><summary>The diagram as text</summary><ul><li><strong>Bin</strong>, a class<ul><li>private field <code>material: String</code></li><li>private field <code>capacity: int</code></li><li>private field <code>load: int</code></li><li>public constructor <code>Bin(material: String, capacity: int)</code></li><li>public method <code>getMaterial(): String</code></li><li>public method <code>add(kilos: int): boolean</code></li><li>public method <code>empty(): void</code></li><li>public method <code>toString(): String</code></li></ul></li></ul></details></figure>\n\n\n- A **constructor** is the class's name with its parameters in parentheses, and nothing after them: a constructor has no return type, in a diagram as in Java.\n- A **method** is its name, its parameters in parentheses, a colon and its **return type**: `getMaterial(): String` returns a String. A method that returns nothing has `void`.\n- Each **parameter** is written like a field, name first: `add(kilos: int)` takes an int called `kilos`. Parameters are separated by commas, and a method without parameters has empty parentheses.\n- The sign in front is the visibility again. Constructors and methods that other classes call are public, `+`. A private helper method gets a `-`.\n- Constructors come first, then methods.\n\nSo each line gives you a header:\n\n| In the box | In Java |\n|---|---|\n| `+Bin(material: String, capacity: int)` | `public Bin(String material, int capacity)` |\n| `+getMaterial(): String` | `public String getMaterial()` |\n| `+add(kilos: int): boolean` | `public boolean add(int kilos)` |\n| `+empty(): void` | `public void empty()` |\n\n`toString` is one of Bin's methods, so it has a line too. `@Override` isn't shown: a box shows headers, and nothing above them or inside them.\n\n### What a box doesn't say\n\nThe box gives every header, but not what the methods do. Does `add` refuse a load that doesn't fit? What does `toString` return? A diagram leaves that to the code, or, before the code exists, to words. The team that drew this box agreed that a new bin is empty, that `add` puts the load in and returns `true` only if the bin's load stays within its capacity (otherwise it changes nothing and returns `false`), and that `empty` sets the load back to 0. With those words and the box, the class almost writes itself:\n\n```java\npublic class Main {\n    public static void main(String[] args) {\n        Bin glass = new Bin(\"glass\", 500);\n        System.out.println(glass.add(300));\n        System.out.println(glass.add(250));\n        System.out.println(glass);\n        glass.empty();\n        System.out.println(glass.add(250) + \" \" + glass.getMaterial());\n    }\n}\n// ==== Bin.java ====\npublic class Bin {\n    private String material;\n    private int capacity;\n    private int load;\n\n    public Bin(String material, int capacity) {\n        this.material = material;\n        this.capacity = capacity;\n        this.load = 0;\n    }\n\n    public String getMaterial() {\n        return this.material;\n    }\n\n    public boolean add(int kilos) {\n        if (this.load + kilos > this.capacity) {\n            return false;\n        }\n        this.load += kilos;\n        return true;\n    }\n\n    public void empty() {\n        this.load = 0;\n    }\n\n    @Override\n    public String toString() {\n        return this.material + \": \" + this.load + \"/\" + this.capacity + \" kg\";\n    }\n}\n```\n\n```output\ntrue\nfalse\nglass: 300/500 kg\ntrue glass\n```\n\nThe challenges in this module work the same way: a box, and words that say what the methods do. Follow the box's headers exactly. Other classes call the methods by those names, with those types, and a header that's different can make their calls fail to compile, or quietly change what they compute.\n","task":"The ward gives each of its beds an object. Write the class `Bed` in `Bed.java`, as this box shows:\n\n\n<figure class=\"uml\"><div class=\"uml-scroll\" tabindex=\"0\" role=\"group\" aria-label=\"Class diagram of Bed\">\n<svg class=\"uml-svg\" viewBox=\"0 0 223 164\" width=\"223\" height=\"164\" style=\"width:13.94rem;min-width:12.78rem;aspect-ratio:223/164\" font-size=\"12\" aria-hidden=\"true\" focusable=\"false\"><rect class=\"u-bg\" fill=\"none\" x=\"6\" y=\"6\" width=\"211\" height=\"152\"/><rect class=\"u-head\" fill=\"none\" x=\"6\" y=\"6\" width=\"211\" height=\"24\"/><text x=\"111.5\" y=\"22\" text-anchor=\"middle\" class=\"u-name\">Bed</text><text x=\"14\" y=\"46\">-number: int</text><text x=\"14\" y=\"62\">-patient: String</text><text x=\"14\" y=\"86\">+Bed(number: int)</text><text x=\"14\" y=\"102\">+isFree(): boolean</text><text x=\"14\" y=\"118\">+assign(name: String): void</text><text x=\"14\" y=\"134\">+release(): void</text><text x=\"14\" y=\"150\">+toString(): String</text><path class=\"u-sep\" fill=\"none\" d=\"M6 30h211M6 70h211\"/><rect class=\"u-frame\" fill=\"none\" x=\"6\" y=\"6\" width=\"211\" height=\"152\"/></svg>\n</div><details class=\"uml-text\"><summary>The diagram as text</summary><ul><li><strong>Bed</strong>, a class<ul><li>private field <code>number: int</code></li><li>private field <code>patient: String</code></li><li>public constructor <code>Bed(number: int)</code></li><li>public method <code>isFree(): boolean</code></li><li>public method <code>assign(name: String): void</code></li><li>public method <code>release(): void</code></li><li>public method <code>toString(): String</code></li></ul></li></ul></details></figure>\n\n\n- A new bed is free: its patient is `null`.\n- `assign` puts the patient's name in the bed, and `release` makes the bed free again.\n- `isFree` says whether the bed is free.\n- `toString` returns `Bed 4: free` for a free bed and `Bed 4: Ines Moreau` for a bed with a patient, with the bed's own number and patient.\n\nThe check runs:\n\n```java\nBed bed = new Bed(4);\nSystem.out.println(bed + \" \" + bed.isFree());\nbed.assign(\"Ines Moreau\");\nSystem.out.println(bed + \" \" + bed.isFree());\nbed.release();\nSystem.out.println(bed);\n```\n\nand expects:\n\n```\nBed 4: free true\nBed 4: Ines Moreau false\nBed 4: free\n```\n","kind":"code","seed":"// ==== Bed.java ====\npublic class Bed {\n\n}\n\n// ==== Main.java ====\npublic class Main {\n    public static void main(String[] args) {\n        Bed bed = new Bed(4);\n        System.out.println(bed + \" \" + bed.isFree());\n        bed.assign(\"Ines Moreau\");\n        System.out.println(bed + \" \" + bed.isFree());\n        bed.release();\n        System.out.println(bed);\n    }\n}\n","solution":"// ==== Bed.java ====\npublic class Bed {\n    private int number;\n    private String patient;\n\n    public Bed(int number) {\n        this.number = number;\n        this.patient = null;\n    }\n\n    public boolean isFree() {\n        return this.patient == null;\n    }\n\n    public void assign(String name) {\n        this.patient = name;\n    }\n\n    public void release() {\n        this.patient = null;\n    }\n\n    @Override\n    public String toString() {\n        if (this.isFree()) {\n            return \"Bed \" + this.number + \": free\";\n        }\n        return \"Bed \" + this.number + \": \" + this.patient;\n    }\n}\n\n// ==== Main.java ====\npublic class Main {\n    public static void main(String[] args) {\n        Bed bed = new Bed(4);\n        System.out.println(bed + \" \" + bed.isFree());\n        bed.assign(\"Ines Moreau\");\n        System.out.println(bed + \" \" + bed.isFree());\n        bed.release();\n        System.out.println(bed);\n    }\n}\n","hints":["Start with the two instance variables from the box's fields, then the constructor `public Bed(int number)`. Each method line becomes a header: `+assign(name: String): void` is `public void assign(String name)`.","`isFree` returns `this.patient == null`, and `release` sets the patient back to `null`. `toString` checks `isFree()` and returns one text or the other."],"tests":[{"name":"Test 1","stdin":"","call":"Bed bed = new Bed(4);\nSystem.out.println(bed + \" \" + bed.isFree());\nbed.assign(\"Ines Moreau\");\nSystem.out.println(bed + \" \" + bed.isFree());\nbed.release();\nSystem.out.println(bed);\n","expect":"Bed 4: free true\nBed 4: Ines Moreau false\nBed 4: free","hidden":false},{"name":"Test 2","stdin":"","call":"Bed first = new Bed(1);\nBed second = new Bed(2);\nsecond.assign(\"Oskar Lund\");\nSystem.out.println(first.isFree() + \" \" + second.isFree());\nSystem.out.println(first + \" / \" + second);\nsecond.release();\nfirst.assign(\"Mei Tan\");\nSystem.out.println(first + \" / \" + second);\n","expect":"true false\nBed 1: free / Bed 2: Oskar Lund\nBed 1: Mei Tan / Bed 2: free","hidden":true}],"require":[{"pattern":"\\bprivate\\s+String\\s+patient\\s*;","message":"The box's field `-patient: String` is `private String patient;`."},{"pattern":"\\bpublic\\s+void\\s+assign\\s*\\(\\s*String\\s+\\w+\\s*\\)","message":"The box's line `+assign(name: String): void` is the header `public void assign(String name)`."}],"forbid":[],"more":[{"task":"A garden center's greenhouses open their vents when it gets warm. The team drew this box, and `Main.java` was written from it:\n\n\n<figure class=\"uml\"><div class=\"uml-scroll\" tabindex=\"0\" role=\"group\" aria-label=\"Class diagram of Greenhouse\">\n<svg class=\"uml-svg\" viewBox=\"0 0 331 196\" width=\"331\" height=\"196\" style=\"width:20.69rem;min-width:18.97rem;aspect-ratio:331/196\" font-size=\"12\" aria-hidden=\"true\" focusable=\"false\"><rect class=\"u-bg\" fill=\"none\" x=\"6\" y=\"6\" width=\"319\" height=\"184\"/><rect class=\"u-head\" fill=\"none\" x=\"6\" y=\"6\" width=\"319\" height=\"24\"/><text x=\"165.5\" y=\"22\" text-anchor=\"middle\" class=\"u-name\">Greenhouse</text><text x=\"14\" y=\"46\">-name: String</text><text x=\"14\" y=\"62\">-degrees: double</text><text x=\"14\" y=\"78\">-open: boolean</text><text x=\"14\" y=\"102\">+Greenhouse(name: String, degrees: double)</text><text x=\"14\" y=\"118\">+getName(): String</text><text x=\"14\" y=\"134\">+getDegrees(): double</text><text x=\"14\" y=\"150\">+isOpen(): boolean</text><text x=\"14\" y=\"166\">+warm(by: double): void</text><text x=\"14\" y=\"182\">+openVents(): void</text><path class=\"u-sep\" fill=\"none\" d=\"M6 30h319M6 86h319\"/><rect class=\"u-frame\" fill=\"none\" x=\"6\" y=\"6\" width=\"319\" height=\"184\"/></svg>\n</div><details class=\"uml-text\"><summary>The diagram as text</summary><ul><li><strong>Greenhouse</strong>, a class<ul><li>private field <code>name: String</code></li><li>private field <code>degrees: double</code></li><li>private field <code>open: boolean</code></li><li>public constructor <code>Greenhouse(name: String, degrees: double)</code></li><li>public method <code>getName(): String</code></li><li>public method <code>getDegrees(): double</code></li><li>public method <code>isOpen(): boolean</code></li><li>public method <code>warm(by: double): void</code></li><li>public method <code>openVents(): void</code></li></ul></li></ul></details></figure>\n\n\nIn `Greenhouse.java`, three method headers don't match the box, so the program doesn't compile. Fix them (and anything inside those methods that has to change with them), so that the class matches the box. Leave `Main.java` as it is. The program should print:\n\n```\nPalm house: true, 26.0 degrees\n```\n","kind":"code","seed":"// ==== Greenhouse.java ====\npublic class Greenhouse {\n    private String name;\n    private double degrees;\n    private boolean open;\n\n    public Greenhouse(String name, double degrees) {\n        this.name = name;\n        this.degrees = degrees;\n        this.open = false;\n    }\n\n    public String getName() {\n        return this.name;\n    }\n\n    public int getDegrees() {\n        return this.degrees;\n    }\n\n    public boolean isOpen() {\n        return this.open;\n    }\n\n    public void warm(int by) {\n        this.degrees += by;\n    }\n\n    private void openVents() {\n        this.open = true;\n    }\n}\n\n// ==== Main.java ====\npublic class Main {\n    public static void main(String[] args) {\n        Greenhouse palm = new Greenhouse(\"Palm house\", 24.5);\n        palm.warm(1.5);\n        if (palm.getDegrees() > 25) {\n            palm.openVents();\n        }\n        System.out.println(palm.getName() + \": \" + palm.isOpen() + \", \" + palm.getDegrees() + \" degrees\");\n    }\n}\n","solution":"// ==== Greenhouse.java ====\npublic class Greenhouse {\n    private String name;\n    private double degrees;\n    private boolean open;\n\n    public Greenhouse(String name, double degrees) {\n        this.name = name;\n        this.degrees = degrees;\n        this.open = false;\n    }\n\n    public String getName() {\n        return this.name;\n    }\n\n    public double getDegrees() {\n        return this.degrees;\n    }\n\n    public boolean isOpen() {\n        return this.open;\n    }\n\n    public void warm(double by) {\n        this.degrees += by;\n    }\n\n    public void openVents() {\n        this.open = true;\n    }\n}\n\n// ==== Main.java ====\npublic class Main {\n    public static void main(String[] args) {\n        Greenhouse palm = new Greenhouse(\"Palm house\", 24.5);\n        palm.warm(1.5);\n        if (palm.getDegrees() > 25) {\n            palm.openVents();\n        }\n        System.out.println(palm.getName() + \": \" + palm.isOpen() + \", \" + palm.getDegrees() + \" degrees\");\n    }\n}\n","hints":["Read javac's messages, then compare each method's header with its line in the box: the sign in front, the parameter's type, and the return type after the colon.","`getDegrees(): double` returns a `double`, `warm(by: double)` takes a `double`, and the `+` in front of `openVents` makes it public."],"tests":[{"name":"The program's output","stdin":"","expect":"Palm house: true, 26.0 degrees","hidden":false},{"name":"Test 2","stdin":"","call":"Greenhouse cactus = new Greenhouse(\"Cactus house\", 30.0);\nSystem.out.println(cactus.isOpen() + \" \" + cactus.getDegrees());\ncactus.warm(0.5);\ncactus.openVents();\nSystem.out.println(cactus.getName() + \" \" + cactus.isOpen() + \" \" + cactus.getDegrees());\n","expect":"false 30.0\nCactus house true 30.5","hidden":true}],"require":[{"pattern":"\\bpublic\\s+double\\s+getDegrees\\s*\\(\\s*\\)","message":"The box's line `+getDegrees(): double` is the header `public double getDegrees()`."},{"pattern":"\\bpublic\\s+void\\s+warm\\s*\\(\\s*double\\s+\\w+\\s*\\)","message":"The box's line `+warm(by: double): void` is the header `public void warm(double by)`."},{"pattern":"\\bpublic\\s+void\\s+openVents\\s*\\(\\s*\\)","message":"The `+` in front of `openVents(): void` means public: `public void openVents()`."}],"forbid":[]},{"task":"A board-game café lends games to its guests, and pieces go missing. Write the class `GameBox` in `GameBox.java`, as this box shows:\n\n\n<figure class=\"uml\"><div class=\"uml-scroll\" tabindex=\"0\" role=\"group\" aria-label=\"Class diagram of GameBox\">\n<svg class=\"uml-svg\" viewBox=\"0 0 288 196\" width=\"288\" height=\"196\" style=\"width:18rem;min-width:16.5rem;aspect-ratio:288/196\" font-size=\"12\" aria-hidden=\"true\" focusable=\"false\"><rect class=\"u-bg\" fill=\"none\" x=\"6\" y=\"6\" width=\"276\" height=\"184\"/><rect class=\"u-head\" fill=\"none\" x=\"6\" y=\"6\" width=\"276\" height=\"24\"/><text x=\"144\" y=\"22\" text-anchor=\"middle\" class=\"u-name\">GameBox</text><text x=\"14\" y=\"46\">-title: String</text><text x=\"14\" y=\"62\">-pieces: int</text><text x=\"14\" y=\"78\">-missing: int</text><text x=\"14\" y=\"102\">+GameBox(title: String, pieces: int)</text><text x=\"14\" y=\"118\">+lose(count: int): void</text><text x=\"14\" y=\"134\">+find(count: int): void</text><text x=\"14\" y=\"150\">+isComplete(): boolean</text><text x=\"14\" y=\"166\">+toString(): String</text><text x=\"14\" y=\"182\">-present(): int</text><path class=\"u-sep\" fill=\"none\" d=\"M6 30h276M6 86h276\"/><rect class=\"u-frame\" fill=\"none\" x=\"6\" y=\"6\" width=\"276\" height=\"184\"/></svg>\n</div><details class=\"uml-text\"><summary>The diagram as text</summary><ul><li><strong>GameBox</strong>, a class<ul><li>private field <code>title: String</code></li><li>private field <code>pieces: int</code></li><li>private field <code>missing: int</code></li><li>public constructor <code>GameBox(title: String, pieces: int)</code></li><li>public method <code>lose(count: int): void</code></li><li>public method <code>find(count: int): void</code></li><li>public method <code>isComplete(): boolean</code></li><li>public method <code>toString(): String</code></li><li>private method <code>present(): int</code></li></ul></li></ul></details></figure>\n\n\n- A new box has all its pieces: none are missing.\n- `lose` adds to the missing pieces. `find` takes found pieces off them, but never below 0.\n- `isComplete` says whether no pieces are missing.\n- `present` is a private helper that returns how many pieces are in the box. `toString` uses it, and returns `Harbor Lights: 80 of 84 pieces`, with the box's own title and numbers.\n\nThe check runs:\n\n```java\nGameBox box = new GameBox(\"Harbor Lights\", 84);\nbox.lose(5);\nbox.find(1);\nSystem.out.println(box + \" \" + box.isComplete());\nbox.find(10);\nSystem.out.println(box + \" \" + box.isComplete());\n```\n\nand expects:\n\n```\nHarbor Lights: 80 of 84 pieces false\nHarbor Lights: 84 of 84 pieces true\n```\n","kind":"code","seed":"// ==== GameBox.java ====\npublic class GameBox {\n\n}\n\n// ==== Main.java ====\npublic class Main {\n    public static void main(String[] args) {\n        GameBox box = new GameBox(\"Harbor Lights\", 84);\n        box.lose(5);\n        box.find(1);\n        System.out.println(box + \" \" + box.isComplete());\n        box.find(10);\n        System.out.println(box + \" \" + box.isComplete());\n    }\n}\n","solution":"// ==== GameBox.java ====\npublic class GameBox {\n    private String title;\n    private int pieces;\n    private int missing;\n\n    public GameBox(String title, int pieces) {\n        this.title = title;\n        this.pieces = pieces;\n        this.missing = 0;\n    }\n\n    public void lose(int count) {\n        this.missing += count;\n    }\n\n    public void find(int count) {\n        this.missing -= count;\n        if (this.missing < 0) {\n            this.missing = 0;\n        }\n    }\n\n    public boolean isComplete() {\n        return this.missing == 0;\n    }\n\n    @Override\n    public String toString() {\n        return this.title + \": \" + this.present() + \" of \" + this.pieces + \" pieces\";\n    }\n\n    private int present() {\n        return this.pieces - this.missing;\n    }\n}\n\n// ==== Main.java ====\npublic class Main {\n    public static void main(String[] args) {\n        GameBox box = new GameBox(\"Harbor Lights\", 84);\n        box.lose(5);\n        box.find(1);\n        System.out.println(box + \" \" + box.isComplete());\n        box.find(10);\n        System.out.println(box + \" \" + box.isComplete());\n    }\n}\n","hints":["Three instance variables, a constructor that sets `missing` to 0, and a method for each line of the box. The `-` in front of `present` makes it `private int present()`.","`find` subtracts, then sets `missing` back to 0 if it went below. `present()` returns the pieces minus the missing ones, and `toString` calls `this.present()`."],"tests":[{"name":"Test 1","stdin":"","call":"GameBox box = new GameBox(\"Harbor Lights\", 84);\nbox.lose(5);\nbox.find(1);\nSystem.out.println(box + \" \" + box.isComplete());\nbox.find(10);\nSystem.out.println(box + \" \" + box.isComplete());\n","expect":"Harbor Lights: 80 of 84 pieces false\nHarbor Lights: 84 of 84 pieces true","hidden":false},{"name":"Test 2","stdin":"","call":"GameBox tiles = new GameBox(\"Word Tiles\", 100);\nSystem.out.println(tiles + \" \" + tiles.isComplete());\ntiles.lose(3);\ntiles.lose(4);\nSystem.out.println(tiles);\ntiles.find(7);\nSystem.out.println(tiles.isComplete());\n","expect":"Word Tiles: 100 of 100 pieces true\nWord Tiles: 93 of 100 pieces\ntrue","hidden":true}],"require":[{"pattern":"\\bprivate\\s+int\\s+present\\s*\\(\\s*\\)","message":"The box's line `-present(): int` is a private method: `private int present()`."},{"pattern":"\\bpresent\\s*\\(\\s*\\)","min":2,"message":"Call the helper `present()` in `toString`."}],"forbid":[]}]}