{"id":"object-methods-getters","slug":"getters","title":"Getters","text":"### Private variables\n\nModule 17 kept every instance variable `private`, so that only the class's own code can change it. Private also means code outside the class can't even read it: `basil.height` in `main` doesn't compile (`height has private access in Plant`). But `main` often has a good reason to read a value, for example to compare two plants.\n\n### Getters\n\nThe way in is a method of the class that returns the value. A method whose only job is to return an instance variable is called a **getter**. It's named `get` followed by the variable's name with a capital letter: `getHeight()` for `height`.\n\n```java\npublic class Main {\n    public static void main(String[] args) {\n        Plant basil = new Plant(\"basil\", 12);\n        Plant fern = new Plant(\"fern\", 30);\n        basil.grow(5);\n        System.out.println(\"The \" + basil.getName() + \" is \" + basil.getHeight() + \" cm\");\n        if (fern.getHeight() > basil.getHeight()) {\n            System.out.println(\"The \" + fern.getName() + \" is taller\");\n        }\n    }\n}\n// ==== Plant.java ====\npublic class Plant {\n    private String name;\n    private int height;\n\n    public Plant(String name, int height) {\n        this.name = name;\n        this.height = height;\n    }\n\n    public void grow(int cm) {\n        this.height = this.height + cm;\n    }\n\n    public String getName() {\n        return this.name;\n    }\n\n    public int getHeight() {\n        return this.height;\n    }\n}\n```\n\n```output\nThe basil is 17 cm\nThe fern is taller\n```\n\n- Code outside the class can now **read** the height, but it still can't **set** it. The height changes only through the class's own methods, such as `grow`, so the class stays in charge of its data.\n- A getter is an ordinary method that returns a value, so `basil.getHeight()` can go in a print line, a comparison or a calculation.\n- The getter of a `boolean` variable is usually named with `is`: a variable `private boolean ripe` gets `public boolean isRipe()`.\n\n### Setters\n\nA method that gives a variable a new value is a **setter**:\n\n```java\npublic void setName(String name) {\n    this.name = name;\n}\n```\n\nWrite a setter only when other code really needs to change that value freely. A method with a meaning, such as `grow(5)`, is often better than `setHeight(...)`: it says what happens, and the class can check the value, as `cut` did in module 17. A class doesn't need a getter and a setter for every variable either, only for the ones its users need.\n","task":"A `Planet` has a name and a number of moons. Add two getters, `getName()` and `getMoons()`, and a method `hasMoons()` that returns `true` when the planet has at least one moon. It isn't stored in a variable of its own: work it out from `moons`. The check creates `new Planet(\"Mars\", 2)` and prints what the three methods return:\n\n```\nMars\n2\ntrue\n```\n","kind":"code","seed":"// ==== Planet.java ====\npublic class Planet {\n    private String name;\n    private int moons;\n\n    public Planet(String name, int moons) {\n        this.name = name;\n        this.moons = moons;\n    }\n\n    // Write getName, getMoons and hasMoons here.\n}\n\n// ==== Main.java ====\npublic class Main {\n    public static void main(String[] args) {\n        Planet planet = new Planet(\"Mars\", 2);\n        if (planet.hasMoons()) {\n            System.out.println(planet.getName() + \" has \" + planet.getMoons() + \" moons\");\n        }\n    }\n}\n","solution":"// ==== Planet.java ====\npublic class Planet {\n    private String name;\n    private int moons;\n\n    public Planet(String name, int moons) {\n        this.name = name;\n        this.moons = moons;\n    }\n\n    public String getName() {\n        return this.name;\n    }\n\n    public int getMoons() {\n        return this.moons;\n    }\n\n    public boolean hasMoons() {\n        return this.moons > 0;\n    }\n}\n\n// ==== Main.java ====\npublic class Main {\n    public static void main(String[] args) {\n        Planet planet = new Planet(\"Mars\", 2);\n        if (planet.hasMoons()) {\n            System.out.println(planet.getName() + \" has \" + planet.getMoons() + \" moons\");\n        }\n    }\n}\n","hints":["`getName` returns a String, `getMoons` an int and `hasMoons` a boolean. None of them has parameters.","`public String getName() { return this.name; }`, the same way for the moons, and `hasMoons()` returns the comparison `this.moons > 0`."],"tests":[{"name":"Test 1","stdin":"","call":"Planet planet = new Planet(\"Mars\", 2);\nSystem.out.println(planet.getName());\nSystem.out.println(planet.getMoons());\nSystem.out.println(planet.hasMoons());\n","expect":"Mars\n2\ntrue","hidden":false},{"name":"Test 2","stdin":"","call":"Planet planet = new Planet(\"Venus\", 0);\nSystem.out.println(planet.getMoons() + \" moons for \" + planet.getName());\nSystem.out.println(planet.hasMoons());\n","expect":"0 moons for Venus\nfalse","hidden":true},{"name":"Test 3","stdin":"","call":"Planet earth = new Planet(\"Earth\", 1);\nPlanet mars = new Planet(\"Mars\", 2);\nSystem.out.println(earth.getMoons() + mars.getMoons());\nSystem.out.println(earth.getName() + \" \" + earth.hasMoons());\n","expect":"3\nEarth true","hidden":true}],"require":[],"forbid":[{"pattern":"\\bpublic\\s+(String|int|boolean)\\s+(name|moons)\\s*;","message":"Keep the instance variables private: the methods give access to them."}],"more":[{"task":"People change their phone numbers. The `Contact` class has getters for the name and the phone number; add a setter `setPhone(String phone)` that stores a new number. The check prints the number, sets a new one and prints the contact's name and number:\n\n```\n040 123\nNoor: 050 987\n```\n","kind":"code","seed":"// ==== Contact.java ====\npublic class Contact {\n    private String name;\n    private String phone;\n\n    public Contact(String name, String phone) {\n        this.name = name;\n        this.phone = phone;\n    }\n\n    public String getName() {\n        return this.name;\n    }\n\n    public String getPhone() {\n        return this.phone;\n    }\n\n    // Write the setPhone method here.\n}\n\n// ==== Main.java ====\npublic class Main {\n    public static void main(String[] args) {\n        Contact contact = new Contact(\"Noor\", \"040 123\");\n        contact.setPhone(\"050 987\");\n        System.out.println(contact.getName() + \": \" + contact.getPhone());\n    }\n}\n","solution":"// ==== Contact.java ====\npublic class Contact {\n    private String name;\n    private String phone;\n\n    public Contact(String name, String phone) {\n        this.name = name;\n        this.phone = phone;\n    }\n\n    public String getName() {\n        return this.name;\n    }\n\n    public String getPhone() {\n        return this.phone;\n    }\n\n    public void setPhone(String phone) {\n        this.phone = phone;\n    }\n}\n\n// ==== Main.java ====\npublic class Main {\n    public static void main(String[] args) {\n        Contact contact = new Contact(\"Noor\", \"040 123\");\n        contact.setPhone(\"050 987\");\n        System.out.println(contact.getName() + \": \" + contact.getPhone());\n    }\n}\n","hints":["A setter gives nothing back, so it's `void`, and it gets the new value as a parameter: `public void setPhone(String phone) {`.","Its one line stores the parameter in the instance variable: `this.phone = phone;`"],"tests":[{"name":"Test 1","stdin":"","call":"Contact contact = new Contact(\"Noor\", \"040 123\");\nSystem.out.println(contact.getPhone());\ncontact.setPhone(\"050 987\");\nSystem.out.println(contact.getName() + \": \" + contact.getPhone());\n","expect":"040 123\nNoor: 050 987","hidden":false},{"name":"Test 2","stdin":"","call":"Contact first = new Contact(\"Ilse\", \"111\");\nContact second = new Contact(\"Tomas\", \"222\");\nsecond.setPhone(\"333\");\nSystem.out.println(first.getPhone());\nSystem.out.println(second.getPhone());\n","expect":"111\n333","hidden":true},{"name":"Test 3","stdin":"","call":"Contact contact = new Contact(\"Rafa\", \"0401\");\ncontact.setPhone(\"0402\");\ncontact.setPhone(\"0403\");\nSystem.out.println(contact.getPhone());\n","expect":"0403","hidden":true}],"require":[],"forbid":[]},{"task":"What does this program print? Watch what changes the pencil and what doesn't.\n","kind":"predict","seed":"public class Main {\n    public static void main(String[] args) {\n        Pencil pencil = new Pencil(20);\n        int length = pencil.getLength();\n        length = length - 5;\n        System.out.println(length);\n        System.out.println(pencil.getLength());\n        pencil.sharpen(30);\n        System.out.println(pencil.getLength());\n    }\n}\n// ==== Pencil.java ====\npublic class Pencil {\n    private int length;\n\n    public Pencil(int length) {\n        this.length = length;\n    }\n\n    public void sharpen(int turns) {\n        this.length = this.length - turns / 10;\n    }\n\n    public int getLength() {\n        return this.length;\n    }\n}\n","solution":"public class Main {\n    public static void main(String[] args) {\n        Pencil pencil = new Pencil(20);\n        int length = pencil.getLength();\n        length = length - 5;\n        System.out.println(length);\n        System.out.println(pencil.getLength());\n        pencil.sharpen(30);\n        System.out.println(pencil.getLength());\n    }\n}\n// ==== Pencil.java ====\npublic class Pencil {\n    private int length;\n\n    public Pencil(int length) {\n        this.length = length;\n    }\n\n    public void sharpen(int turns) {\n        this.length = this.length - turns / 10;\n    }\n\n    public int getLength() {\n        return this.length;\n    }\n}\n","hints":["`getLength()` returns the value 20, and `main` stores it in a variable of its own. Changing that variable doesn't touch the pencil.","`sharpen(30)` takes `30 / 10`, which is 3, off the pencil's own length."],"tests":[{"name":"Output","stdin":"","expect":"15\n20\n17","hidden":false}],"require":[],"forbid":[],"lines":["15","20","17"]}]}