{"id":"classes-many-objects","slug":"several-objects","title":"Several objects","text":"One class can make as many objects as a program needs, and each object keeps its own state: calling a method on one of them never changes the others. The values for new objects often come from the user:\n\n```java\nimport java.util.Scanner;\n\npublic class Main {\n    public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);\n        System.out.println(\"First plant:\");\n        String first = scanner.nextLine();\n        System.out.println(\"Second plant:\");\n        String second = scanner.nextLine();\n\n        Plant left = new Plant(first, 10);\n        Plant right = new Plant(second, 10);\n        left.grow(8);\n        right.grow(3);\n        left.cut(12);\n        left.printInfo();\n        right.printInfo();\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 printInfo() {\n        System.out.println(this.name + \", \" + this.height + \" cm\");\n    }\n\n    public void grow(int cm) {\n        this.height = this.height + cm;\n    }\n\n    public void cut(int cm) {\n        this.height = this.height - cm;\n        if (this.height < 5) {\n            this.height = 5;\n        }\n    }\n}\n```\n\n```input\nmint\nbasil\n```\n\n```output\nFirst plant:\nSecond plant:\nmint, 6 cm\nbasil, 13 cm\n```\n\n- `left` and `right` are built from the same class, with names read from the user, and each has its own `name` and `height`.\n- `left.grow(8)` and `left.cut(12)` change only `left`: the variable in front of the dot decides which object a method works on. `right` only grew by 3.\n\nA program can use as many classes as it needs, each in its own file next to `Main.java`, and `main` can make objects of all of them: a garden program could have a `Plant` class and a `Lamp` class, and create a few of each. Module 19 shows how to keep any number of objects in a list.\n","task":"It's a snail race, and `Snail.java` is ready. The program reads the names of two snails, one per line. Create a Snail for each. The race has three rounds: in each round, read how many centimeters the first snail crawls and then how many the second crawls, and give each number to the right snail with `crawl`. At the end, print where both snails are with `printDistance()`. For the input `Speedy`, `Shelly`, `3`, `2`, `1`, `4`, `5` and `1`, one per line, the program prints:\n\n```\nSpeedy has crawled 9 cm\nShelly has crawled 7 cm\n```\n","kind":"code","seed":"// ==== Main.java ====\nimport java.util.Scanner;\n\npublic class Main {\n    public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);\n        String firstName = scanner.nextLine();\n        String secondName = scanner.nextLine();\n\n    }\n}\n\n// ==== Snail.java ====\npublic class Snail {\n    private String name;\n    private int distance;\n\n    public Snail(String name) {\n        this.name = name;\n        this.distance = 0;\n    }\n\n    public void crawl(int cm) {\n        this.distance = this.distance + cm;\n    }\n\n    public void printDistance() {\n        System.out.println(this.name + \" has crawled \" + this.distance + \" cm\");\n    }\n}\n","solution":"// ==== Main.java ====\nimport java.util.Scanner;\n\npublic class Main {\n    public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);\n        String firstName = scanner.nextLine();\n        String secondName = scanner.nextLine();\n        Snail first = new Snail(firstName);\n        Snail second = new Snail(secondName);\n        for (int round = 0; round < 3; round++) {\n            first.crawl(Integer.valueOf(scanner.nextLine()));\n            second.crawl(Integer.valueOf(scanner.nextLine()));\n        }\n        first.printDistance();\n        second.printDistance();\n    }\n}\n\n// ==== Snail.java ====\npublic class Snail {\n    private String name;\n    private int distance;\n\n    public Snail(String name) {\n        this.name = name;\n        this.distance = 0;\n    }\n\n    public void crawl(int cm) {\n        this.distance = this.distance + cm;\n    }\n\n    public void printDistance() {\n        System.out.println(this.name + \" has crawled \" + this.distance + \" cm\");\n    }\n}\n","hints":["Two objects, one for each name: `Snail first = new Snail(firstName);` and the same for the second.","A loop of three rounds. Each round reads two numbers: `first.crawl(Integer.valueOf(scanner.nextLine()));`, then the same for `second`."],"tests":[{"name":"Test 1","stdin":"Speedy\nShelly\n3\n2\n1\n4\n5\n1\n","expect":"Speedy has crawled 9 cm\nShelly has crawled 7 cm","hidden":false},{"name":"Test 2","stdin":"Turbo\nPebble\n0\n6\n0\n6\n10\n0\n","expect":"Turbo has crawled 10 cm\nPebble has crawled 12 cm","hidden":true},{"name":"Test 3","stdin":"Slow Sam\nSlower Sue\n1\n1\n1\n1\n1\n1\n","expect":"Slow Sam has crawled 3 cm\nSlower Sue has crawled 3 cm","hidden":true}],"require":[{"pattern":"\\bnew\\s+Snail\\s*\\(","min":2,"message":"Create two snails, one for each name, with `new Snail(...)`."},{"pattern":"\\.crawl\\s*\\(","message":"Move the snails with their `crawl` method."},{"pattern":"\\.printDistance\\s*\\(\\s*\\)","min":2,"message":"Print both snails with their `printDistance()` method."}],"forbid":[],"more":[{"task":"What does this program print? There are three candles, and two of them have the same scent.\n","kind":"predict","seed":"public class Main {\n    public static void main(String[] args) {\n        Candle a = new Candle(\"vanilla\", 60);\n        Candle b = new Candle(\"pine\", 60);\n        Candle c = new Candle(\"vanilla\", 30);\n        a.burn(20);\n        c.burn(20);\n        b.burn(70);\n        a.burn(10);\n        a.printInfo();\n        b.printInfo();\n        c.printInfo();\n    }\n}\n// ==== Candle.java ====\npublic class Candle {\n    private String scent;\n    private int minutes;\n\n    public Candle(String scent, int minutes) {\n        this.scent = scent;\n        this.minutes = minutes;\n    }\n\n    public void burn(int time) {\n        this.minutes = this.minutes - time;\n        if (this.minutes < 0) {\n            this.minutes = 0;\n        }\n    }\n\n    public void printInfo() {\n        System.out.println(this.scent + \": \" + this.minutes + \" minutes left\");\n    }\n}\n","solution":"public class Main {\n    public static void main(String[] args) {\n        Candle a = new Candle(\"vanilla\", 60);\n        Candle b = new Candle(\"pine\", 60);\n        Candle c = new Candle(\"vanilla\", 30);\n        a.burn(20);\n        c.burn(20);\n        b.burn(70);\n        a.burn(10);\n        a.printInfo();\n        b.printInfo();\n        c.printInfo();\n    }\n}\n// ==== Candle.java ====\npublic class Candle {\n    private String scent;\n    private int minutes;\n\n    public Candle(String scent, int minutes) {\n        this.scent = scent;\n        this.minutes = minutes;\n    }\n\n    public void burn(int time) {\n        this.minutes = this.minutes - time;\n        if (this.minutes < 0) {\n            this.minutes = 0;\n        }\n    }\n\n    public void printInfo() {\n        System.out.println(this.scent + \": \" + this.minutes + \" minutes left\");\n    }\n}\n","hints":["Follow each candle on its own. `a` burns 20 and then 10 minutes, `c` burns 20, and `b` burns 70.","`a` and `c` have the same scent but are two separate objects. `b` would go below 0, so `burn` stops it at 0."],"tests":[{"name":"Output","stdin":"","expect":"vanilla: 30 minutes left\npine: 0 minutes left\nvanilla: 10 minutes left","hidden":false}],"require":[],"forbid":[],"lines":["vanilla: 30 minutes left","pine: 0 minutes left","vanilla: 10 minutes left"]},{"task":"Now write the class yourself. `Main.java` is ready: it reads the names of two players and then dice rolls, one per line, until the line `end`. The rolls go to the players in turns, first player first, and at the end both positions are printed. Write the class `Player` in `Player.java`:\n\n- `Player(String name)` builds a player, who starts on square 1.\n- `move(int squares)` moves the player on. The board has 30 squares, and a move that would go past square 30 stops at square 30.\n- `printPosition()` prints where the player is, as in the output below.\n\nFor the input `Ada`, `Ben`, `6`, `3`, `5`, `4` and `end`, one per line, the program prints:\n\n```\nAda is on square 12\nBen is on square 8\n```\n","kind":"code","seed":"// ==== Player.java ====\npublic class Player {\n\n}\n\n// ==== Main.java ====\nimport java.util.Scanner;\n\npublic class Main {\n    public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);\n        Player first = new Player(scanner.nextLine());\n        Player second = new Player(scanner.nextLine());\n        boolean firstPlayersTurn = true;\n        while (true) {\n            String line = scanner.nextLine();\n            if (line.equals(\"end\")) {\n                break;\n            }\n            int roll = Integer.valueOf(line);\n            if (firstPlayersTurn) {\n                first.move(roll);\n            } else {\n                second.move(roll);\n            }\n            firstPlayersTurn = !firstPlayersTurn;\n        }\n        first.printPosition();\n        second.printPosition();\n    }\n}\n","solution":"// ==== Player.java ====\npublic class Player {\n    private String name;\n    private int square;\n\n    public Player(String name) {\n        this.name = name;\n        this.square = 1;\n    }\n\n    public void move(int squares) {\n        this.square = this.square + squares;\n        if (this.square > 30) {\n            this.square = 30;\n        }\n    }\n\n    public void printPosition() {\n        System.out.println(this.name + \" is on square \" + this.square);\n    }\n}\n\n// ==== Main.java ====\nimport java.util.Scanner;\n\npublic class Main {\n    public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);\n        Player first = new Player(scanner.nextLine());\n        Player second = new Player(scanner.nextLine());\n        boolean firstPlayersTurn = true;\n        while (true) {\n            String line = scanner.nextLine();\n            if (line.equals(\"end\")) {\n                break;\n            }\n            int roll = Integer.valueOf(line);\n            if (firstPlayersTurn) {\n                first.move(roll);\n            } else {\n                second.move(roll);\n            }\n            firstPlayersTurn = !firstPlayersTurn;\n        }\n        first.printPosition();\n        second.printPosition();\n    }\n}\n","hints":["Two private instance variables: the name and the square. The constructor stores the name and sets the square to 1.","`move` adds to the square, and then an `if` sets it back to 30 when it went past 30. `printPosition` prints `this.name + \" is on square \" + this.square`."],"tests":[{"name":"Test 1","stdin":"Ada\nBen\n6\n3\n5\n4\nend\n","expect":"Ada is on square 12\nBen is on square 8","hidden":false},{"name":"Test 2","stdin":"Mira\nOtto\n6\n6\n6\n6\n6\n6\n6\n6\n6\nend\n","expect":"Mira is on square 30\nOtto is on square 25","hidden":true},{"name":"Test 3","stdin":"Lu\nKit\nend\n","expect":"Lu is on square 1\nKit is on square 1","hidden":true},{"name":"Test 4","stdin":"","call":"Player player = new Player(\"Kim\");\nplayer.printPosition();\nplayer.move(40);\nplayer.printPosition();\n","expect":"Kim is on square 1\nKim is on square 30","hidden":true},{"name":"Test 5","stdin":"","call":"Player player = new Player(\"Rae\");\nplayer.move(28);\nplayer.printPosition();\nplayer.move(1);\nplayer.printPosition();\n","expect":"Rae is on square 29\nRae is on square 30","hidden":true}],"require":[{"pattern":"\\bprivate\\s+\\w+\\s+\\w+\\s*[;=]","min":2,"message":"Keep the player's name and square in private instance variables."}],"forbid":[]}]}