{"id":"class-diagrams-boxes","slug":"boxes","title":"A class as a box","text":"A program of two or three classes fits in your head. A program of ten classes, each with its instance variables, constructors and methods, doesn't, and neither does a program that a team is about to write together. So programmers draw their classes: a box for each class, and lines between the boxes for how the classes are connected. Such a drawing is a **class diagram**.\n\nClass diagrams have a standard form, part of **UML**, the Unified Modeling Language, so that a diagram drawn by one programmer can be read by anyone who knows UML. This module teaches you to read them, to turn them into classes, and to draw the classes you write.\n\n### A box with fields\n\nA recycling center has a bin for each material: glass, paper, metal and so on. Its program keeps each bin in an object of this class:\n\n```java\npublic class Bin {\n    private String material;\n    private int capacity;\n    private int load;\n}\n```\n\nIn a class diagram, the class is a box:\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 151 100\" width=\"151\" height=\"100\" style=\"width:9.44rem;min-width:8.66rem;aspect-ratio:151/100\" font-size=\"12\" aria-hidden=\"true\" focusable=\"false\"><rect class=\"u-bg\" fill=\"none\" x=\"6\" y=\"6\" width=\"139\" height=\"88\"/><rect class=\"u-head\" fill=\"none\" x=\"6\" y=\"6\" width=\"139\" height=\"24\"/><text x=\"75.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><path class=\"u-sep\" fill=\"none\" d=\"M6 30h139M6 86h139\"/><rect class=\"u-frame\" fill=\"none\" x=\"6\" y=\"6\" width=\"139\" height=\"88\"/></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></ul></li></ul></details></figure>\n\n\n- The class's name is at the top, in bold.\n- Under a line come the class's instance variables, one per line. Diagrams call them **fields** (or attributes).\n- Each field is written as its name, a colon and its type: `capacity: int`. That's the other way around from Java, where the type comes first (`int capacity`).\n- The sign in front is the field's **visibility**: `-` for `private` and `+` for `public`. Since this course keeps instance variables private, nearly every field you'll see starts with `-`. (You may also meet `#` for `protected`, from module 34.)\n\nUnder each drawing, \"The diagram as text\" says the same in words, which is handy when you want to check what a sign means.\n\nA diagram is a plan, not a program: it doesn't run, and it may leave things out. This step's boxes show only fields. The next step adds constructors and methods.\n\n### From a box to a class\n\nA box tells you what to write. Here's the box of a pickup: a load that the center's truck collects from an address.\n\n\n<figure class=\"uml\"><div class=\"uml-scroll\" tabindex=\"0\" role=\"group\" aria-label=\"Class diagram of Pickup\">\n<svg class=\"uml-svg\" viewBox=\"0 0 144 100\" width=\"144\" height=\"100\" style=\"width:9rem;min-width:8.25rem;aspect-ratio:144/100\" font-size=\"12\" aria-hidden=\"true\" focusable=\"false\"><rect class=\"u-bg\" fill=\"none\" x=\"6\" y=\"6\" width=\"132\" height=\"88\"/><rect class=\"u-head\" fill=\"none\" x=\"6\" y=\"6\" width=\"132\" height=\"24\"/><text x=\"72\" y=\"22\" text-anchor=\"middle\" class=\"u-name\">Pickup</text><text x=\"14\" y=\"46\">-address: String</text><text x=\"14\" y=\"62\">-kilos: double</text><text x=\"14\" y=\"78\">-done: boolean</text><path class=\"u-sep\" fill=\"none\" d=\"M6 30h132M6 86h132\"/><rect class=\"u-frame\" fill=\"none\" x=\"6\" y=\"6\" width=\"132\" height=\"88\"/></svg>\n</div><details class=\"uml-text\"><summary>The diagram as text</summary><ul><li><strong>Pickup</strong>, a class<ul><li>private field <code>address: String</code></li><li>private field <code>kilos: double</code></li><li>private field <code>done: boolean</code></li></ul></li></ul></details></figure>\n\n\nEach line becomes one instance variable, in the same order:\n\n- `-address: String` is `private String address;`\n- `-kilos: double` is `private double kilos;`\n- `-done: boolean` is `private boolean done;`\n\nWith a constructor and a `toString`, which this box doesn't show, the class can be used:\n\n```java\npublic class Main {\n    public static void main(String[] args) {\n        Pickup pickup = new Pickup(\"12 Mill Road\", 35.5);\n        System.out.println(pickup);\n    }\n}\n// ==== Pickup.java ====\npublic class Pickup {\n    private String address;\n    private double kilos;\n    private boolean done;\n\n    public Pickup(String address, double kilos) {\n        this.address = address;\n        this.kilos = kilos;\n        this.done = false;\n    }\n\n    @Override\n    public String toString() {\n        return this.address + \": \" + this.kilos + \" kg\";\n    }\n}\n```\n\n```output\n12 Mill Road: 35.5 kg\n```\n\nThe types in a box are Java's own: `int`, `double`, `boolean`, `String`, or `ArrayList<String>` for a field that holds a list of Strings. Write them exactly as the box says. A class with an `int` where its box says `double`, or a public field where the box says `-`, no longer matches the plan, and code that others wrote from the same plan may not work with it.\n","task":"A hospital ward keeps track of its patients. Here's the box of a patient:\n\n\n<figure class=\"uml\"><div class=\"uml-scroll\" tabindex=\"0\" role=\"group\" aria-label=\"Class diagram of Patient\">\n<svg class=\"uml-svg\" viewBox=\"0 0 172 100\" width=\"172\" height=\"100\" style=\"width:10.75rem;min-width:9.86rem;aspect-ratio:172/100\" font-size=\"12\" aria-hidden=\"true\" focusable=\"false\"><rect class=\"u-bg\" fill=\"none\" x=\"6\" y=\"6\" width=\"160\" height=\"88\"/><rect class=\"u-head\" fill=\"none\" x=\"6\" y=\"6\" width=\"160\" height=\"24\"/><text x=\"86\" y=\"22\" text-anchor=\"middle\" class=\"u-name\">Patient</text><text x=\"14\" y=\"46\">-name: String</text><text x=\"14\" y=\"62\">-room: int</text><text x=\"14\" y=\"78\">-temperature: double</text><path class=\"u-sep\" fill=\"none\" d=\"M6 30h160M6 86h160\"/><rect class=\"u-frame\" fill=\"none\" x=\"6\" y=\"6\" width=\"160\" height=\"88\"/></svg>\n</div><details class=\"uml-text\"><summary>The diagram as text</summary><ul><li><strong>Patient</strong>, a class<ul><li>private field <code>name: String</code></li><li>private field <code>room: int</code></li><li>private field <code>temperature: double</code></li></ul></li></ul></details></figure>\n\n\nFill in the blanks in `Patient.java`, so that its instance variables match the box. The constructor and `toString` are ready.\n","kind":"fill","seed":"public class Main {\n    public static void main(String[] args) {\n        Patient patient = new Patient(\"Ines Moreau\", 12, 38.4);\n        System.out.println(patient);\n    }\n}\n// ==== Patient.java ====\npublic class Patient {\n    [[private]] String name;\n    private [[int]] room;\n    private [[double]] [[temperature]];\n\n    public Patient(String name, int room, double temperature) {\n        this.name = name;\n        this.room = room;\n        this.temperature = temperature;\n    }\n\n    @Override\n    public String toString() {\n        return this.name + \", room \" + this.room + \", \" + this.temperature + \" degrees\";\n    }\n}\n","solution":"public class Main {\n    public static void main(String[] args) {\n        Patient patient = new Patient(\"Ines Moreau\", 12, 38.4);\n        System.out.println(patient);\n    }\n}\n// ==== Patient.java ====\npublic class Patient {\n    private String name;\n    private int room;\n    private double temperature;\n\n    public Patient(String name, int room, double temperature) {\n        this.name = name;\n        this.room = room;\n        this.temperature = temperature;\n    }\n\n    @Override\n    public String toString() {\n        return this.name + \", room \" + this.room + \", \" + this.temperature + \" degrees\";\n    }\n}\n","hints":["Each line of the box is one instance variable, with the name first in the box and the type first in Java: `-room: int` is `private int room;`.","`-` stands for `private`. The blanks are `private`, `int`, `double` and `temperature`."],"tests":[{"name":"Output","stdin":"","expect":"Ines Moreau, room 12, 38.4 degrees","hidden":false}],"require":[{"pattern":"\\bprivate\\s+String\\s+name\\s*;","message":"The `-` in front of `name: String` means private: `private String name;`."}],"forbid":[],"more":[{"task":"The ward's nurses have a class too. `Nurse.java` has a constructor and two methods, but its instance variables are missing, so it doesn't compile. Add them, as this box shows:\n\n\n<figure class=\"uml\"><div class=\"uml-scroll\" tabindex=\"0\" role=\"group\" aria-label=\"Class diagram of Nurse\">\n<svg class=\"uml-svg\" viewBox=\"0 0 172 100\" width=\"172\" height=\"100\" style=\"width:10.75rem;min-width:9.86rem;aspect-ratio:172/100\" font-size=\"12\" aria-hidden=\"true\" focusable=\"false\"><rect class=\"u-bg\" fill=\"none\" x=\"6\" y=\"6\" width=\"160\" height=\"88\"/><rect class=\"u-head\" fill=\"none\" x=\"6\" y=\"6\" width=\"160\" height=\"24\"/><text x=\"86\" y=\"22\" text-anchor=\"middle\" class=\"u-name\">Nurse</text><text x=\"14\" y=\"46\">-name: String</text><text x=\"14\" y=\"62\">-nightShift: boolean</text><text x=\"14\" y=\"78\">-patients: int</text><path class=\"u-sep\" fill=\"none\" d=\"M6 30h160M6 86h160\"/><rect class=\"u-frame\" fill=\"none\" x=\"6\" y=\"6\" width=\"160\" height=\"88\"/></svg>\n</div><details class=\"uml-text\"><summary>The diagram as text</summary><ul><li><strong>Nurse</strong>, a class<ul><li>private field <code>name: String</code></li><li>private field <code>nightShift: boolean</code></li><li>private field <code>patients: int</code></li></ul></li></ul></details></figure>\n\n\nLeave the constructor and the methods as they are. The program should print:\n\n```\nTomas Berg (night shift): 2 patients\n```\n","kind":"code","seed":"// ==== Nurse.java ====\npublic class Nurse {\n\n    public Nurse(String name, boolean nightShift) {\n        this.name = name;\n        this.nightShift = nightShift;\n        this.patients = 0;\n    }\n\n    public void takePatient() {\n        this.patients++;\n    }\n\n    @Override\n    public String toString() {\n        String shift = \"day\";\n        if (this.nightShift) {\n            shift = \"night\";\n        }\n        return this.name + \" (\" + shift + \" shift): \" + this.patients + \" patients\";\n    }\n}\n\n// ==== Main.java ====\npublic class Main {\n    public static void main(String[] args) {\n        Nurse nurse = new Nurse(\"Tomas Berg\", true);\n        nurse.takePatient();\n        nurse.takePatient();\n        System.out.println(nurse);\n    }\n}\n","solution":"// ==== Nurse.java ====\npublic class Nurse {\n    private String name;\n    private boolean nightShift;\n    private int patients;\n\n    public Nurse(String name, boolean nightShift) {\n        this.name = name;\n        this.nightShift = nightShift;\n        this.patients = 0;\n    }\n\n    public void takePatient() {\n        this.patients++;\n    }\n\n    @Override\n    public String toString() {\n        String shift = \"day\";\n        if (this.nightShift) {\n            shift = \"night\";\n        }\n        return this.name + \" (\" + shift + \" shift): \" + this.patients + \" patients\";\n    }\n}\n\n// ==== Main.java ====\npublic class Main {\n    public static void main(String[] args) {\n        Nurse nurse = new Nurse(\"Tomas Berg\", true);\n        nurse.takePatient();\n        nurse.takePatient();\n        System.out.println(nurse);\n    }\n}\n","hints":["Put the three instance variables at the top of the class, one for each line of the box, in the same order.","`-nightShift: boolean` is `private boolean nightShift;`. Do the same for `name` and `patients`."],"tests":[{"name":"The program's output","stdin":"","expect":"Tomas Berg (night shift): 2 patients","hidden":false},{"name":"Test 2","stdin":"","call":"Nurse day = new Nurse(\"Sara Lind\", false);\nSystem.out.println(day);\nday.takePatient();\nSystem.out.println(day);\n","expect":"Sara Lind (day shift): 0 patients\nSara Lind (day shift): 1 patients","hidden":true}],"require":[{"pattern":"\\bprivate\\s+String\\s+name\\s*;","message":"The box's first line, `-name: String`, is `private String name;`."},{"pattern":"\\bprivate\\s+boolean\\s+nightShift\\s*;","message":"The box's line `-nightShift: boolean` is `private boolean nightShift;`."},{"pattern":"\\bprivate\\s+int\\s+patients\\s*;","message":"The box's line `-patients: int` is `private int patients;`."}],"forbid":[]},{"task":"A garden center planned its shrubs with this box:\n\n\n<figure class=\"uml\"><div class=\"uml-scroll\" tabindex=\"0\" role=\"group\" aria-label=\"Class diagram of Shrub\">\n<svg class=\"uml-svg\" viewBox=\"0 0 144 100\" width=\"144\" height=\"100\" style=\"width:9rem;min-width:8.25rem;aspect-ratio:144/100\" font-size=\"12\" aria-hidden=\"true\" focusable=\"false\"><rect class=\"u-bg\" fill=\"none\" x=\"6\" y=\"6\" width=\"132\" height=\"88\"/><rect class=\"u-head\" fill=\"none\" x=\"6\" y=\"6\" width=\"132\" height=\"24\"/><text x=\"72\" y=\"22\" text-anchor=\"middle\" class=\"u-name\">Shrub</text><text x=\"14\" y=\"46\">-species: String</text><text x=\"14\" y=\"62\">-height: double</text><text x=\"14\" y=\"78\">-potLiters: int</text><path class=\"u-sep\" fill=\"none\" d=\"M6 30h132M6 86h132\"/><rect class=\"u-frame\" fill=\"none\" x=\"6\" y=\"6\" width=\"132\" height=\"88\"/></svg>\n</div><details class=\"uml-text\"><summary>The diagram as text</summary><ul><li><strong>Shrub</strong>, a class<ul><li>private field <code>species: String</code></li><li>private field <code>height: double</code></li><li>private field <code>potLiters: int</code></li></ul></li></ul></details></figure>\n\n\nIn `Shrub.java`, two instance variables don't match the box, and the program prints `Lilac: 19 cm, pot 10 liters`: half centimeters get lost along the way. Fix those two lines, and leave the constructor and the methods as they are. The program should print:\n\n```\nLilac: 20.0 cm, pot 10 liters\n```\n","kind":"code","seed":"// ==== Shrub.java ====\npublic class Shrub {\n    public String species;\n    private int height;\n    private int potLiters;\n\n    public Shrub(String species, int potLiters) {\n        this.species = species;\n        this.height = 0;\n        this.potLiters = potLiters;\n    }\n\n    public void grow(double centimeters) {\n        this.height += centimeters;\n    }\n\n    @Override\n    public String toString() {\n        return this.species + \": \" + this.height + \" cm, pot \" + this.potLiters + \" liters\";\n    }\n}\n\n// ==== Main.java ====\npublic class Main {\n    public static void main(String[] args) {\n        Shrub lilac = new Shrub(\"Lilac\", 10);\n        lilac.grow(12.5);\n        lilac.grow(7.5);\n        System.out.println(lilac);\n    }\n}\n","solution":"// ==== Shrub.java ====\npublic class Shrub {\n    private String species;\n    private double height;\n    private int potLiters;\n\n    public Shrub(String species, int potLiters) {\n        this.species = species;\n        this.height = 0;\n        this.potLiters = potLiters;\n    }\n\n    public void grow(double centimeters) {\n        this.height += centimeters;\n    }\n\n    @Override\n    public String toString() {\n        return this.species + \": \" + this.height + \" cm, pot \" + this.potLiters + \" liters\";\n    }\n}\n\n// ==== Main.java ====\npublic class Main {\n    public static void main(String[] args) {\n        Shrub lilac = new Shrub(\"Lilac\", 10);\n        lilac.grow(12.5);\n        lilac.grow(7.5);\n        System.out.println(lilac);\n    }\n}\n","hints":["Compare each line of the box with its instance variable: the sign (`-` is private), the name and the type.","`species` should be `private`, and `height` should be a `double`. With an `int`, `+=` drops the half centimeter of each `grow`."],"tests":[{"name":"The program's output","stdin":"","expect":"Lilac: 20.0 cm, pot 10 liters","hidden":false},{"name":"Test 2","stdin":"","call":"Shrub box = new Shrub(\"Boxwood\", 3);\nbox.grow(0.5);\nbox.grow(0.25);\nSystem.out.println(box);\n","expect":"Boxwood: 0.75 cm, pot 3 liters","hidden":true}],"require":[{"pattern":"\\bprivate\\s+String\\s+species\\s*;","message":"The `-` in front of `species: String` means private: `private String species;`."},{"pattern":"\\bprivate\\s+double\\s+height\\s*;","message":"The box says `-height: double`, so the instance variable is `private double height;`."}],"forbid":[]}]}