{"id":"interfaces-parameter-type","slug":"parameter-type","title":"An interface as a parameter's type","text":"A watch shop sells products, such as straps and alarm clocks, and it does repairs, which cost 2 dollars a minute. A product and a repair have little in common: a product has a name and a fixed price, and a repair has minutes of work. But at the checkout, both need a line on the receipt and a price. That's an interface:\n\n```java\npublic interface Priced {\n    String label();\n    int price();\n}\n```\n\nA method whose parameter has the type Priced accepts both:\n\n```java\npublic class Main {\n    public static void main(String[] args) {\n        Product strap = new Product(\"Watch strap\", 12);\n        Repair repair = new Repair(25);\n        printLine(strap);\n        printLine(repair);\n        printLine(new Product(\"Alarm clock\", 45));\n    }\n\n    public static void printLine(Priced item) {\n        System.out.println(item.label() + \": \" + item.price() + \" dollars\");\n    }\n}\n// ==== Priced.java ====\npublic interface Priced {\n    String label();\n    int price();\n}\n// ==== Product.java ====\npublic class Product implements Priced {\n    private String name;\n    private int dollars;\n\n    public Product(String name, int dollars) {\n        this.name = name;\n        this.dollars = dollars;\n    }\n\n    @Override\n    public String label() {\n        return this.name;\n    }\n\n    @Override\n    public int price() {\n        return this.dollars;\n    }\n}\n// ==== Repair.java ====\npublic class Repair implements Priced {\n    private int minutes;\n\n    public Repair(int minutes) {\n        this.minutes = minutes;\n    }\n\n    @Override\n    public String label() {\n        return \"Repair, \" + this.minutes + \" minutes\";\n    }\n\n    @Override\n    public int price() {\n        return 2 * this.minutes;\n    }\n}\n```\n\n```output\nWatch strap: 12 dollars\nRepair, 25 minutes: 50 dollars\nAlarm clock: 45 dollars\n```\n\n- `printLine`'s parameter has the type Priced, so the method accepts an object of any class that implements Priced. The call `printLine(strap)` works as if it said `Priced item = strap;`, which compiles because a Product is a Priced.\n- Inside the method, `item` is a Priced variable, like step 3's `device`. The method may call `label()` and `price()`, and each object runs its own: the product gives its fixed price, the repair works its price out from the minutes.\n\n### One method for every kind of item\n\nWithout the interface, `printLine` would need two versions, `printLine(Product item)` and `printLine(Repair item)`, with the same code in each (overloading, module 21). Every new thing the shop sells would need one more.\n\nWith the interface, `printLine` is written once, and it depends only on what it uses: a label and a price. When the shop starts engraving watches, a new class `Engraving` that implements Priced works with `printLine` at once, without any change to it. The last challenge of this step shows that.\n\nJava's own classes work this way too. `System.out.println` can print any object because it has a version whose parameter's type is Object, and step 6 shows that `Collections.sort` takes an interface.\n","task":"In `Checkout.java`, write the class `Checkout` for the watch shop's till. `Priced.java`, `Product.java` and `Repair.java` are ready. A checkout has:\n\n- a constructor without parameters; a new checkout has a total of 0 and no items\n- `scan(Priced item)`, which prints the item's line, such as `Watch strap: 12 dollars`, adds its price to the total, and counts it\n- `total()`, which returns the total in dollars\n- `itemCount()`, which returns how many items have been scanned\n\nThe check runs:\n\n```java\nCheckout checkout = new Checkout();\ncheckout.scan(new Product(\"Watch strap\", 12));\ncheckout.scan(new Repair(25));\nSystem.out.println(\"Total: \" + checkout.total() + \" dollars for \" + checkout.itemCount() + \" items\");\n```\n\nand expects:\n\n```\nWatch strap: 12 dollars\nRepair, 25 minutes: 50 dollars\nTotal: 62 dollars for 2 items\n```\n","kind":"code","seed":"// ==== Checkout.java ====\npublic class Checkout {\n\n}\n\n// ==== Priced.java ====\npublic interface Priced {\n    String label();\n    int price();\n}\n\n// ==== Product.java ====\npublic class Product implements Priced {\n    private String name;\n    private int dollars;\n\n    public Product(String name, int dollars) {\n        this.name = name;\n        this.dollars = dollars;\n    }\n\n    @Override\n    public String label() {\n        return this.name;\n    }\n\n    @Override\n    public int price() {\n        return this.dollars;\n    }\n}\n\n// ==== Repair.java ====\npublic class Repair implements Priced {\n    private int minutes;\n\n    public Repair(int minutes) {\n        this.minutes = minutes;\n    }\n\n    @Override\n    public String label() {\n        return \"Repair, \" + this.minutes + \" minutes\";\n    }\n\n    @Override\n    public int price() {\n        return 2 * this.minutes;\n    }\n}\n\n// ==== Main.java ====\npublic class Main {\n    public static void main(String[] args) {\n        Checkout checkout = new Checkout();\n        checkout.scan(new Product(\"Watch strap\", 12));\n        checkout.scan(new Repair(25));\n        System.out.println(\"Total: \" + checkout.total() + \" dollars for \" + checkout.itemCount() + \" items\");\n    }\n}\n","solution":"// ==== Checkout.java ====\npublic class Checkout {\n    private int total;\n    private int items;\n\n    public Checkout() {\n        this.total = 0;\n        this.items = 0;\n    }\n\n    public void scan(Priced item) {\n        System.out.println(item.label() + \": \" + item.price() + \" dollars\");\n        this.total += item.price();\n        this.items++;\n    }\n\n    public int total() {\n        return this.total;\n    }\n\n    public int itemCount() {\n        return this.items;\n    }\n}\n\n// ==== Priced.java ====\npublic interface Priced {\n    String label();\n    int price();\n}\n\n// ==== Product.java ====\npublic class Product implements Priced {\n    private String name;\n    private int dollars;\n\n    public Product(String name, int dollars) {\n        this.name = name;\n        this.dollars = dollars;\n    }\n\n    @Override\n    public String label() {\n        return this.name;\n    }\n\n    @Override\n    public int price() {\n        return this.dollars;\n    }\n}\n\n// ==== Repair.java ====\npublic class Repair implements Priced {\n    private int minutes;\n\n    public Repair(int minutes) {\n        this.minutes = minutes;\n    }\n\n    @Override\n    public String label() {\n        return \"Repair, \" + this.minutes + \" minutes\";\n    }\n\n    @Override\n    public int price() {\n        return 2 * this.minutes;\n    }\n}\n\n// ==== Main.java ====\npublic class Main {\n    public static void main(String[] args) {\n        Checkout checkout = new Checkout();\n        checkout.scan(new Product(\"Watch strap\", 12));\n        checkout.scan(new Repair(25));\n        System.out.println(\"Total: \" + checkout.total() + \" dollars for \" + checkout.itemCount() + \" items\");\n    }\n}\n","hints":["Checkout needs two instance variables: the total and the number of items. Neither of them cares whether an item is a product or a repair.","The method is `public void scan(Priced item)`. It prints `item.label() + \": \" + item.price() + \" dollars\"`, adds `item.price()` to the total, and adds one to the count."],"tests":[{"name":"Test 1","stdin":"","call":"Checkout checkout = new Checkout();\ncheckout.scan(new Product(\"Watch strap\", 12));\ncheckout.scan(new Repair(25));\nSystem.out.println(\"Total: \" + checkout.total() + \" dollars for \" + checkout.itemCount() + \" items\");\n","expect":"Watch strap: 12 dollars\nRepair, 25 minutes: 50 dollars\nTotal: 62 dollars for 2 items","hidden":false},{"name":"Test 2","stdin":"","call":"Checkout till = new Checkout();\nSystem.out.println(till.total() + \" \" + till.itemCount());\nPriced clock = new Product(\"Alarm clock\", 45);\ntill.scan(clock);\ntill.scan(clock);\ntill.scan(new Repair(5));\nSystem.out.println(till.total() + \" \" + till.itemCount());\n","expect":"0 0\nAlarm clock: 45 dollars\nAlarm clock: 45 dollars\nRepair, 5 minutes: 10 dollars\n100 3","hidden":true},{"name":"Test 3","stdin":"","call":"Checkout first = new Checkout();\nCheckout second = new Checkout();\nfirst.scan(new Repair(60));\nsecond.scan(new Product(\"Travel case\", 30));\nsecond.scan(new Product(\"Battery\", 8));\nSystem.out.println(first.total() + \" \" + first.itemCount() + \" \" + second.total() + \" \" + second.itemCount());\n","expect":"Repair, 60 minutes: 120 dollars\nTravel case: 30 dollars\nBattery: 8 dollars\n120 1 38 2","hidden":true}],"require":[{"pattern":"\\bvoid\\s+scan\\s*\\(\\s*Priced\\s+\\w+\\s*\\)","message":"Write the method as `public void scan(Priced item)`, so that it takes products and repairs alike."}],"forbid":[],"more":[{"task":"The method `cheaper` takes two priced things, and returns the label of the cheaper one. What does this program print?\n","kind":"predict","seed":"public class Main {\n    public static void main(String[] args) {\n        System.out.println(cheaper(new Product(\"Stopwatch\", 30), new Repair(12)));\n        System.out.println(cheaper(new Repair(20), new Product(\"Wall clock\", 40)));\n        Priced chain = new Product(\"Chain\", 18);\n        System.out.println(cheaper(chain, chain) + \" \" + cheaper(new Repair(9), chain));\n    }\n\n    public static String cheaper(Priced first, Priced second) {\n        if (first.price() <= second.price()) {\n            return first.label();\n        }\n        return second.label();\n    }\n}\n// ==== Priced.java ====\npublic interface Priced {\n    String label();\n    int price();\n}\n// ==== Product.java ====\npublic class Product implements Priced {\n    private String name;\n    private int dollars;\n\n    public Product(String name, int dollars) {\n        this.name = name;\n        this.dollars = dollars;\n    }\n\n    @Override\n    public String label() {\n        return this.name;\n    }\n\n    @Override\n    public int price() {\n        return this.dollars;\n    }\n}\n// ==== Repair.java ====\npublic class Repair implements Priced {\n    private int minutes;\n\n    public Repair(int minutes) {\n        this.minutes = minutes;\n    }\n\n    @Override\n    public String label() {\n        return \"Repair, \" + this.minutes + \" minutes\";\n    }\n\n    @Override\n    public int price() {\n        return 2 * this.minutes;\n    }\n}\n","solution":"public class Main {\n    public static void main(String[] args) {\n        System.out.println(cheaper(new Product(\"Stopwatch\", 30), new Repair(12)));\n        System.out.println(cheaper(new Repair(20), new Product(\"Wall clock\", 40)));\n        Priced chain = new Product(\"Chain\", 18);\n        System.out.println(cheaper(chain, chain) + \" \" + cheaper(new Repair(9), chain));\n    }\n\n    public static String cheaper(Priced first, Priced second) {\n        if (first.price() <= second.price()) {\n            return first.label();\n        }\n        return second.label();\n    }\n}\n// ==== Priced.java ====\npublic interface Priced {\n    String label();\n    int price();\n}\n// ==== Product.java ====\npublic class Product implements Priced {\n    private String name;\n    private int dollars;\n\n    public Product(String name, int dollars) {\n        this.name = name;\n        this.dollars = dollars;\n    }\n\n    @Override\n    public String label() {\n        return this.name;\n    }\n\n    @Override\n    public int price() {\n        return this.dollars;\n    }\n}\n// ==== Repair.java ====\npublic class Repair implements Priced {\n    private int minutes;\n\n    public Repair(int minutes) {\n        this.minutes = minutes;\n    }\n\n    @Override\n    public String label() {\n        return \"Repair, \" + this.minutes + \" minutes\";\n    }\n\n    @Override\n    public int price() {\n        return 2 * this.minutes;\n    }\n}\n","hints":["A repair costs 2 dollars a minute: 12 minutes is 24 dollars, 20 minutes is 40, and 9 minutes is 18. Each object's own `price` runs.","With `<=`, a tie goes to `first`. Repair(20) and the wall clock both cost 40, and Repair(9) and the chain both cost 18."],"tests":[{"name":"Output","stdin":"","expect":"Repair, 12 minutes\nRepair, 20 minutes\nChain Repair, 9 minutes","hidden":false}],"require":[],"forbid":[],"lines":["Repair, 12 minutes","Repair, 20 minutes","Chain Repair, 9 minutes"]},{"task":"The shop starts engraving watches: 3 dollars a letter, but never more than 30 dollars for one engraving. In `Engraving.java`, write the class `Engraving`, which implements Priced, with:\n\n- a constructor `Engraving(String text)`, where the text is one word, such as a name, so its `length()` is its number of letters\n- `label()`, which returns `Engraving, Anna`, with the engraving's own text\n- `price()`, which returns the price in dollars\n\n`Main.java` has this step's `printLine`, and it doesn't change: it takes engravings as soon as Engraving implements Priced. The check runs:\n\n```java\nprintLine(new Engraving(\"Anna\"));\nprintLine(new Engraving(\"Christopher\"));\nprintLine(new Product(\"Alarm clock\", 45));\n```\n\nand expects:\n\n```\nEngraving, Anna: 12 dollars\nEngraving, Christopher: 30 dollars\nAlarm clock: 45 dollars\n```\n","kind":"code","seed":"// ==== Engraving.java ====\npublic class Engraving {\n\n}\n\n// ==== Priced.java ====\npublic interface Priced {\n    String label();\n    int price();\n}\n\n// ==== Product.java ====\npublic class Product implements Priced {\n    private String name;\n    private int dollars;\n\n    public Product(String name, int dollars) {\n        this.name = name;\n        this.dollars = dollars;\n    }\n\n    @Override\n    public String label() {\n        return this.name;\n    }\n\n    @Override\n    public int price() {\n        return this.dollars;\n    }\n}\n\n// ==== Main.java ====\npublic class Main {\n    public static void main(String[] args) {\n        printLine(new Engraving(\"Anna\"));\n        printLine(new Engraving(\"Christopher\"));\n        printLine(new Product(\"Alarm clock\", 45));\n    }\n\n    public static void printLine(Priced item) {\n        System.out.println(item.label() + \": \" + item.price() + \" dollars\");\n    }\n}\n","solution":"// ==== Engraving.java ====\npublic class Engraving implements Priced {\n    private String text;\n\n    public Engraving(String text) {\n        this.text = text;\n    }\n\n    @Override\n    public String label() {\n        return \"Engraving, \" + this.text;\n    }\n\n    @Override\n    public int price() {\n        int price = 3 * this.text.length();\n        if (price > 30) {\n            return 30;\n        }\n        return price;\n    }\n}\n\n// ==== Priced.java ====\npublic interface Priced {\n    String label();\n    int price();\n}\n\n// ==== Product.java ====\npublic class Product implements Priced {\n    private String name;\n    private int dollars;\n\n    public Product(String name, int dollars) {\n        this.name = name;\n        this.dollars = dollars;\n    }\n\n    @Override\n    public String label() {\n        return this.name;\n    }\n\n    @Override\n    public int price() {\n        return this.dollars;\n    }\n}\n\n// ==== Main.java ====\npublic class Main {\n    public static void main(String[] args) {\n        printLine(new Engraving(\"Anna\"));\n        printLine(new Engraving(\"Christopher\"));\n        printLine(new Product(\"Alarm clock\", 45));\n    }\n\n    public static void printLine(Priced item) {\n        System.out.println(item.label() + \": \" + item.price() + \" dollars\");\n    }\n}\n","hints":["Start with `public class Engraving implements Priced {`, with one instance variable, the text. Both methods have `@Override` above them.","`price()` works out `3 * this.text.length()`, and returns 30 instead when that's more than 30."],"tests":[{"name":"Test 1","stdin":"","call":"printLine(new Engraving(\"Anna\"));\nprintLine(new Engraving(\"Christopher\"));\nprintLine(new Product(\"Alarm clock\", 45));\n","expect":"Engraving, Anna: 12 dollars\nEngraving, Christopher: 30 dollars\nAlarm clock: 45 dollars","hidden":false},{"name":"Test 2","stdin":"","call":"printLine(new Engraving(\"Jo\"));\nprintLine(new Engraving(\"Leonardo\"));\nprintLine(new Engraving(\"Maximilian\"));\n","expect":"Engraving, Jo: 6 dollars\nEngraving, Leonardo: 24 dollars\nEngraving, Maximilian: 30 dollars","hidden":true},{"name":"Test 3","stdin":"","call":"Priced gift = new Engraving(\"Bartholomew\");\nSystem.out.println(gift.price() + \" \" + gift.label());\n","expect":"30 Engraving, Bartholomew","hidden":true}],"require":[{"pattern":"\\bclass\\s+Engraving\\s+implements\\s+Priced\\b","message":"Write the header as `public class Engraving implements Priced`, so that `printLine` accepts engravings."}],"forbid":[]}]}