{"id":"object-interaction-parameter","slug":"object-as-parameter","title":"An object as a parameter","text":"So far, the methods of your classes have taken numbers and Strings as parameters. A parameter can also be an object of one of your own classes, and then two objects can work together. Here a printer prints documents, and each document knows its own title and number of pages:\n\n```java\npublic class Main {\n    public static void main(String[] args) {\n        Printer printer = new Printer(10);\n        Document letter = new Document(\"Letter\", 2);\n        Document report = new Document(\"Report\", 12);\n        printer.print(letter);\n        printer.print(report);\n        printer.print(new Document(\"Poster\", 1));\n        System.out.println(printer);\n    }\n}\n// ==== Printer.java ====\npublic class Printer {\n    private int paper;\n    private int printed;\n\n    public Printer(int paper) {\n        this.paper = paper;\n        this.printed = 0;\n    }\n\n    public void print(Document document) {\n        if (document.getPages() <= this.paper) {\n            this.paper = this.paper - document.getPages();\n            this.printed++;\n            System.out.println(\"Printed \" + document.getTitle());\n        } else {\n            System.out.println(\"Not enough paper for \" + document.getTitle());\n        }\n    }\n\n    public String toString() {\n        return this.printed + \" documents printed, \" + this.paper + \" sheets left\";\n    }\n}\n// ==== Document.java ====\npublic class Document {\n    private String title;\n    private int pages;\n\n    public Document(String title, int pages) {\n        this.title = title;\n        this.pages = pages;\n    }\n\n    public String getTitle() {\n        return this.title;\n    }\n\n    public int getPages() {\n        return this.pages;\n    }\n}\n```\n\n```output\nPrinted Letter\nNot enough paper for Report\nPrinted Poster\n2 documents printed, 7 sheets left\n```\n\n- The parameter's type is the name of the class: `public void print(Document document)`. The method takes a Document and nothing else: `printer.print(\"Letter\")` doesn't compile.\n- Inside `print`, `document` is the Document it was given. The printer uses it through its public methods, `getTitle()` and `getPages()`, just as `main` would. Writing `document.pages` in `Printer` doesn't compile, because `pages` is private to the `Document` class.\n- The call can give an object that's in a variable, as in `printer.print(letter)`, or a new one made right in the call: `printer.print(new Document(\"Poster\", 1))`.\n- `this.paper` is the printer's own variable, and `document.getPages()` asks the document. Each object keeps its own data, and the method brings the two together.\n\n### The object itself, not a copy\n\nAs module 22 showed, a parameter of a class type holds a reference to an object, just like any other variable of that type: `printer.print(letter)` gives the method a reference to the very object in `letter`, not a copy of it. So when a method changes the object it was given, the change is still there after the method ends:\n\n```java\npublic class Main {\n    public static void main(String[] args) {\n        Phone phone = new Phone(15);\n        Charger charger = new Charger(2);\n        System.out.println(phone);\n        charger.charge(phone, 30);\n        System.out.println(phone);\n        charger.charge(phone, 60);\n        System.out.println(phone);\n    }\n}\n// ==== Charger.java ====\npublic class Charger {\n    private int percentPerMinute;\n\n    public Charger(int percentPerMinute) {\n        this.percentPerMinute = percentPerMinute;\n    }\n\n    public void charge(Phone phone, int minutes) {\n        phone.addBattery(minutes * this.percentPerMinute);\n    }\n}\n// ==== Phone.java ====\npublic class Phone {\n    private int battery;\n\n    public Phone(int battery) {\n        this.battery = battery;\n    }\n\n    public void addBattery(int percent) {\n        this.battery = this.battery + percent;\n        if (this.battery > 100) {\n            this.battery = 100;\n        }\n    }\n\n    public String toString() {\n        return \"Battery \" + this.battery + \"%\";\n    }\n}\n```\n\n```output\nBattery 15%\nBattery 75%\nBattery 100%\n```\n\n`charge` changes the phone through the phone's own method, `addBattery`, and `main` sees the new level in `phone`: the variable in `main` and the parameter refer to the same Phone. The charger can't set `battery` directly. Only Phone's own code can, and it makes sure the battery never goes over 100%.\n","task":"A piggy bank counts the coins put into it and adds up their value in cents. In `PiggyBank.java`, write the method `insert(Coin coin)`: it adds one to `coins`, and the coin's value to `cents`. `Coin.java` is ready, and a coin tells its value with `getCents()`. The check runs:\n\n```java\nPiggyBank piggy = new PiggyBank();\npiggy.insert(new Coin(50));\npiggy.insert(new Coin(20));\npiggy.insert(new Coin(100));\nSystem.out.println(piggy);\n```\n\nand expects:\n\n```\nCoins: 3, total 170 cents\n```\n","kind":"code","seed":"// ==== PiggyBank.java ====\npublic class PiggyBank {\n    private int coins;\n    private int cents;\n\n    public PiggyBank() {\n        this.coins = 0;\n        this.cents = 0;\n    }\n\n    // Write the insert method here.\n\n    public String toString() {\n        return \"Coins: \" + this.coins + \", total \" + this.cents + \" cents\";\n    }\n}\n\n// ==== Coin.java ====\npublic class Coin {\n    private int cents;\n\n    public Coin(int cents) {\n        this.cents = cents;\n    }\n\n    public int getCents() {\n        return this.cents;\n    }\n}\n\n// ==== Main.java ====\npublic class Main {\n    public static void main(String[] args) {\n        PiggyBank piggy = new PiggyBank();\n        piggy.insert(new Coin(50));\n        piggy.insert(new Coin(20));\n        piggy.insert(new Coin(100));\n        System.out.println(piggy);\n    }\n}\n","solution":"// ==== PiggyBank.java ====\npublic class PiggyBank {\n    private int coins;\n    private int cents;\n\n    public PiggyBank() {\n        this.coins = 0;\n        this.cents = 0;\n    }\n\n    public void insert(Coin coin) {\n        this.coins++;\n        this.cents = this.cents + coin.getCents();\n    }\n\n    public String toString() {\n        return \"Coins: \" + this.coins + \", total \" + this.cents + \" cents\";\n    }\n}\n\n// ==== Coin.java ====\npublic class Coin {\n    private int cents;\n\n    public Coin(int cents) {\n        this.cents = cents;\n    }\n\n    public int getCents() {\n        return this.cents;\n    }\n}\n\n// ==== Main.java ====\npublic class Main {\n    public static void main(String[] args) {\n        PiggyBank piggy = new PiggyBank();\n        piggy.insert(new Coin(50));\n        piggy.insert(new Coin(20));\n        piggy.insert(new Coin(100));\n        System.out.println(piggy);\n    }\n}\n","hints":["The parameter's type is the class: `public void insert(Coin coin) {`. Inside the method, `coin` is the coin that was put in.","`this.coins++;` counts the coin, and `this.cents = this.cents + coin.getCents();` adds its value. `coin.cents` doesn't compile in PiggyBank, because it's private to Coin."],"tests":[{"name":"Test 1","stdin":"","call":"PiggyBank piggy = new PiggyBank();\npiggy.insert(new Coin(50));\npiggy.insert(new Coin(20));\npiggy.insert(new Coin(100));\nSystem.out.println(piggy);\n","expect":"Coins: 3, total 170 cents","hidden":false},{"name":"Test 2","stdin":"","call":"PiggyBank piggy = new PiggyBank();\nSystem.out.println(piggy);\nCoin big = new Coin(200);\npiggy.insert(big);\npiggy.insert(big);\nSystem.out.println(piggy);\n","expect":"Coins: 0, total 0 cents\nCoins: 2, total 400 cents","hidden":true},{"name":"Test 3","stdin":"","call":"PiggyBank first = new PiggyBank();\nPiggyBank second = new PiggyBank();\nfirst.insert(new Coin(5));\nsecond.insert(new Coin(10));\nsecond.insert(new Coin(1));\nSystem.out.println(first);\nSystem.out.println(second);\n","expect":"Coins: 1, total 5 cents\nCoins: 2, total 11 cents","hidden":true}],"require":[{"pattern":"\\bpublic\\s+void\\s+insert\\s*\\(\\s*Coin\\s+\\w+\\s*\\)","message":"Write the method as `public void insert(Coin coin)`."},{"pattern":"\\.getCents\\s*\\(\\s*\\)","message":"Ask the coin for its value with `getCents()`."}],"forbid":[],"more":[{"task":"What does this program print? Each call to `enter` works with two objects: the gate it's called on and the passport it's given.\n","kind":"predict","seed":"public class Main {\n    public static void main(String[] args) {\n        Passport ana = new Passport(\"Ana\");\n        Passport ben = new Passport(\"Ben\");\n        Gate north = new Gate(\"North gate\");\n        Gate south = new Gate(\"South gate\");\n        north.enter(ana);\n        south.enter(ben);\n        north.enter(ana);\n        south.enter(ana);\n        System.out.println(ana);\n        System.out.println(ben);\n        System.out.println(north);\n    }\n}\n// ==== Gate.java ====\npublic class Gate {\n    private String name;\n    private int entries;\n\n    public Gate(String name) {\n        this.name = name;\n        this.entries = 0;\n    }\n\n    public void enter(Passport passport) {\n        passport.addStamp();\n        this.entries++;\n    }\n\n    public String toString() {\n        return this.name + \": \" + this.entries + \" entries\";\n    }\n}\n// ==== Passport.java ====\npublic class Passport {\n    private String owner;\n    private int stamps;\n\n    public Passport(String owner) {\n        this.owner = owner;\n        this.stamps = 0;\n    }\n\n    public void addStamp() {\n        this.stamps++;\n    }\n\n    public String toString() {\n        return this.owner + \", stamps: \" + this.stamps;\n    }\n}\n","solution":"public class Main {\n    public static void main(String[] args) {\n        Passport ana = new Passport(\"Ana\");\n        Passport ben = new Passport(\"Ben\");\n        Gate north = new Gate(\"North gate\");\n        Gate south = new Gate(\"South gate\");\n        north.enter(ana);\n        south.enter(ben);\n        north.enter(ana);\n        south.enter(ana);\n        System.out.println(ana);\n        System.out.println(ben);\n        System.out.println(north);\n    }\n}\n// ==== Gate.java ====\npublic class Gate {\n    private String name;\n    private int entries;\n\n    public Gate(String name) {\n        this.name = name;\n        this.entries = 0;\n    }\n\n    public void enter(Passport passport) {\n        passport.addStamp();\n        this.entries++;\n    }\n\n    public String toString() {\n        return this.name + \": \" + this.entries + \" entries\";\n    }\n}\n// ==== Passport.java ====\npublic class Passport {\n    private String owner;\n    private int stamps;\n\n    public Passport(String owner) {\n        this.owner = owner;\n        this.stamps = 0;\n    }\n\n    public void addStamp() {\n        this.stamps++;\n    }\n\n    public String toString() {\n        return this.owner + \", stamps: \" + this.stamps;\n    }\n}\n","hints":["`enter` gets the passport itself, not a copy, so `passport.addStamp()` changes the Passport object in `ana` or `ben`. Then the gate counts one more entry of its own.","Ana's passport is given to `enter` three times: twice at the north gate and once at the south gate. Ben's is given once. The north gate counted two entries, both Ana's."],"tests":[{"name":"Output","stdin":"","expect":"Ana, stamps: 3\nBen, stamps: 1\nNorth gate: 2 entries","hidden":false}],"require":[],"forbid":[],"lines":["Ana, stamps: 3","Ben, stamps: 1","North gate: 2 entries"]},{"task":"A kettle pours hot water into cups. `Cup.java` is ready: `space()` returns how many milliliters still fit in the cup, and `fill(int ml)` adds water to it. In `Kettle.java`, write the method `pour(Cup cup)`. It pours until the cup is full or the kettle is empty, whichever comes first, and the kettle then has that much less water. The check runs:\n\n```java\nKettle kettle = new Kettle(500);\nCup mug = new Cup(300);\nCup glass = new Cup(250);\nkettle.pour(mug);\nkettle.pour(glass);\nSystem.out.println(mug);\nSystem.out.println(glass);\nSystem.out.println(kettle);\n```\n\nand expects:\n\n```\n300/300 ml\n200/250 ml\nKettle: 0 ml\n```\n","kind":"code","seed":"// ==== Kettle.java ====\npublic class Kettle {\n    private int water;\n\n    public Kettle(int water) {\n        this.water = water;\n    }\n\n    // Write the pour method here.\n\n    public String toString() {\n        return \"Kettle: \" + this.water + \" ml\";\n    }\n}\n\n// ==== Cup.java ====\npublic class Cup {\n    private int capacity;\n    private int water;\n\n    public Cup(int capacity) {\n        this.capacity = capacity;\n        this.water = 0;\n    }\n\n    public int space() {\n        return this.capacity - this.water;\n    }\n\n    public void fill(int ml) {\n        this.water = this.water + ml;\n    }\n\n    public String toString() {\n        return this.water + \"/\" + this.capacity + \" ml\";\n    }\n}\n\n// ==== Main.java ====\npublic class Main {\n    public static void main(String[] args) {\n        Kettle kettle = new Kettle(500);\n        Cup mug = new Cup(300);\n        Cup glass = new Cup(250);\n        kettle.pour(mug);\n        kettle.pour(glass);\n        System.out.println(mug);\n        System.out.println(glass);\n        System.out.println(kettle);\n    }\n}\n","solution":"// ==== Kettle.java ====\npublic class Kettle {\n    private int water;\n\n    public Kettle(int water) {\n        this.water = water;\n    }\n\n    public void pour(Cup cup) {\n        int amount = Math.min(this.water, cup.space());\n        cup.fill(amount);\n        this.water = this.water - amount;\n    }\n\n    public String toString() {\n        return \"Kettle: \" + this.water + \" ml\";\n    }\n}\n\n// ==== Cup.java ====\npublic class Cup {\n    private int capacity;\n    private int water;\n\n    public Cup(int capacity) {\n        this.capacity = capacity;\n        this.water = 0;\n    }\n\n    public int space() {\n        return this.capacity - this.water;\n    }\n\n    public void fill(int ml) {\n        this.water = this.water + ml;\n    }\n\n    public String toString() {\n        return this.water + \"/\" + this.capacity + \" ml\";\n    }\n}\n\n// ==== Main.java ====\npublic class Main {\n    public static void main(String[] args) {\n        Kettle kettle = new Kettle(500);\n        Cup mug = new Cup(300);\n        Cup glass = new Cup(250);\n        kettle.pour(mug);\n        kettle.pour(glass);\n        System.out.println(mug);\n        System.out.println(glass);\n        System.out.println(kettle);\n    }\n}\n","hints":["The amount to pour is the smaller of two numbers: the kettle's own `this.water` and the cup's `cup.space()`. `Math.min` gives the smaller one.","Then give the cup that amount with `cup.fill(amount);`, and take it from the kettle: `this.water = this.water - amount;`."],"tests":[{"name":"Test 1","stdin":"","call":"Kettle kettle = new Kettle(500);\nCup mug = new Cup(300);\nCup glass = new Cup(250);\nkettle.pour(mug);\nkettle.pour(glass);\nSystem.out.println(mug);\nSystem.out.println(glass);\nSystem.out.println(kettle);\n","expect":"300/300 ml\n200/250 ml\nKettle: 0 ml","hidden":false},{"name":"Test 2","stdin":"","call":"Kettle kettle = new Kettle(1000);\nCup cup = new Cup(200);\ncup.fill(50);\nkettle.pour(cup);\nkettle.pour(cup);\nSystem.out.println(cup);\nSystem.out.println(kettle);\n","expect":"200/200 ml\nKettle: 850 ml","hidden":true},{"name":"Test 3","stdin":"","call":"Kettle kettle = new Kettle(100);\nCup first = new Cup(250);\nCup second = new Cup(300);\nkettle.pour(first);\nkettle.pour(second);\nSystem.out.println(first);\nSystem.out.println(second);\nSystem.out.println(kettle);\n","expect":"100/250 ml\n0/300 ml\nKettle: 0 ml","hidden":true}],"require":[{"pattern":"\\bpublic\\s+void\\s+pour\\s*\\(\\s*Cup\\s+\\w+\\s*\\)","message":"Write the method as `public void pour(Cup cup)`."},{"pattern":"\\.space\\s*\\(\\s*\\)","message":"Ask the cup how much still fits with `space()`."},{"pattern":"\\.fill\\s*\\(","message":"Put the water in the cup with its `fill` method."}],"forbid":[]}]}