{"id":"class-design-constructors","slug":"several-constructors","title":"Several constructors","text":"Some objects are nearly always made the same way. At a café, most coffee orders are for a medium cup, so writing `\"medium\"` in every order gets tiresome. A class can have more than one constructor, and `new` picks the one that fits:\n\n```java\npublic class Main {\n    public static void main(String[] args) {\n        CoffeeOrder first = new CoffeeOrder(\"latte\");\n        CoffeeOrder second = new CoffeeOrder(\"mocha\", \"large\");\n        System.out.println(first);\n        System.out.println(second);\n    }\n}\n// ==== CoffeeOrder.java ====\npublic class CoffeeOrder {\n    private String drink;\n    private String size;\n\n    public CoffeeOrder(String drink) {\n        this.drink = drink;\n        this.size = \"medium\";\n    }\n\n    public CoffeeOrder(String drink, String size) {\n        this.drink = drink;\n        this.size = size;\n    }\n\n    public String toString() {\n        return this.size + \" \" + this.drink;\n    }\n}\n```\n\n```output\nmedium latte\nlarge mocha\n```\n\n- Both constructors have the class's name, but different parameters. Constructors like these are called **overloaded** constructors.\n- Java picks the constructor whose parameters fit the values in `new`. `new CoffeeOrder(\"latte\")` gives one String, so it runs the first constructor. `new CoffeeOrder(\"mocha\", \"large\")` gives two, so it runs the second. Values that fit no constructor, as in `new CoffeeOrder(2)`, don't compile.\n- The first constructor fills in a **default value**: the size used when the order doesn't say one.\n\n### A constructor without parameters\n\nModule 17 showed that Java adds a default constructor, without parameters, only to a class that has no constructor of its own. `CoffeeOrder` has two, so `new CoffeeOrder()` doesn't compile. If the café wants a quick way to order \"the usual\", the class needs a third constructor, written out:\n\n```java\npublic CoffeeOrder() {\n    this.drink = \"filter coffee\";\n    this.size = \"medium\";\n}\n```\n\nA class can have as many constructors as it needs, in any order.\n\n### What makes constructors different\n\nConstructors must differ in their **parameter types**: in the number of parameters, in their types, or in the order of the types. The parameter names don't count. Say the café wants a constructor for a drink and a kind of milk. It takes two Strings, just like the one for a drink and a size, so a call such as `new CoffeeOrder(\"tea\", \"oat\")` couldn't say which one it meant. javac doesn't wait for such a call: it rejects the second constructor itself, even in a program that never uses it:\n\n```java\npublic class Main {\n    public static void main(String[] args) {\n        System.out.println(\"The café is open\");\n    }\n}\n// ==== CoffeeOrder.java ====\npublic class CoffeeOrder {\n    private String drink;\n    private String size;\n    private String milk;\n\n    public CoffeeOrder(String drink, String size) {\n        this.drink = drink;\n        this.size = size;\n        this.milk = \"none\";\n    }\n\n    public CoffeeOrder(String drink, String milk) {\n        this.drink = drink;\n        this.size = \"medium\";\n        this.milk = milk;\n    }\n}\n```\n\n```javac\nCoffeeOrder.java:12: error: constructor CoffeeOrder(String,String) is already defined in class CoffeeOrder\n    public CoffeeOrder(String drink, String milk) {\n           ^\n1 error\n```\n\n`CoffeeOrder(String,String)` is the constructor as javac sees it: only the types, no names. A constructor for a drink, a size and a milk, `CoffeeOrder(String drink, String size, String milk)`, would be fine, since it takes three values.\n","task":"A library loan is usually for 14 days. `Loan.java` has a constructor that takes the book's title and the number of days. Add a second constructor, `Loan(String title)`, for a loan of 14 days. The check runs:\n\n```java\nLoan usual = new Loan(\"Moby Dick\");\nLoan quick = new Loan(\"Atlas of Birds\", 7);\nSystem.out.println(usual);\nSystem.out.println(quick);\n```\n\nand expects:\n\n```\nMoby Dick, due in 14 days\nAtlas of Birds, due in 7 days\n```\n","kind":"code","seed":"// ==== Loan.java ====\npublic class Loan {\n    private String title;\n    private int days;\n\n    public Loan(String title, int days) {\n        this.title = title;\n        this.days = days;\n    }\n\n    // Write the second constructor here.\n\n    public String toString() {\n        return this.title + \", due in \" + this.days + \" days\";\n    }\n}\n\n// ==== Main.java ====\npublic class Main {\n    public static void main(String[] args) {\n        Loan usual = new Loan(\"Moby Dick\");\n        Loan quick = new Loan(\"Atlas of Birds\", 7);\n        System.out.println(usual);\n        System.out.println(quick);\n    }\n}\n","solution":"// ==== Loan.java ====\npublic class Loan {\n    private String title;\n    private int days;\n\n    public Loan(String title, int days) {\n        this.title = title;\n        this.days = days;\n    }\n\n    public Loan(String title) {\n        this.title = title;\n        this.days = 14;\n    }\n\n    public String toString() {\n        return this.title + \", due in \" + this.days + \" days\";\n    }\n}\n\n// ==== Main.java ====\npublic class Main {\n    public static void main(String[] args) {\n        Loan usual = new Loan(\"Moby Dick\");\n        Loan quick = new Loan(\"Atlas of Birds\", 7);\n        System.out.println(usual);\n        System.out.println(quick);\n    }\n}\n","hints":["The new constructor has the same name and one parameter: `public Loan(String title) {`.","It stores the title from the parameter, and the default for the days: `this.title = title;` and `this.days = 14;`."],"tests":[{"name":"Test 1","stdin":"","call":"Loan usual = new Loan(\"Moby Dick\");\nLoan quick = new Loan(\"Atlas of Birds\", 7);\nSystem.out.println(usual);\nSystem.out.println(quick);\n","expect":"Moby Dick, due in 14 days\nAtlas of Birds, due in 7 days","hidden":false},{"name":"Test 2","stdin":"","call":"Loan loan = new Loan(\"The Hobbit\");\nSystem.out.println(loan);\n","expect":"The Hobbit, due in 14 days","hidden":true},{"name":"Test 3","stdin":"","call":"Loan first = new Loan(\"Emma\", 28);\nLoan second = new Loan(\"Dracula\");\nSystem.out.println(second);\nSystem.out.println(first);\n","expect":"Dracula, due in 14 days\nEmma, due in 28 days","hidden":true}],"require":[],"forbid":[],"more":[{"task":"A snowman has a number of snowballs and a nose. Write three constructors for the `Snowman` class:\n\n- `Snowman()` makes the classic snowman: 3 balls and a `carrot` nose.\n- `Snowman(int balls)` has that many balls, and a `carrot` nose.\n- `Snowman(int balls, String nose)` has the balls and the nose given.\n\nThe instance variables and `toString` are ready. The check prints `new Snowman()`, `new Snowman(4)` and `new Snowman(2, \"pine cone\")`:\n\n```\n3 balls, carrot nose\n4 balls, carrot nose\n2 balls, pine cone nose\n```\n","kind":"code","seed":"// ==== Snowman.java ====\npublic class Snowman {\n    private int balls;\n    private String nose;\n\n    // Write the three constructors here.\n\n    public String toString() {\n        return this.balls + \" balls, \" + this.nose + \" nose\";\n    }\n}\n\n// ==== Main.java ====\npublic class Main {\n    public static void main(String[] args) {\n        System.out.println(new Snowman());\n        System.out.println(new Snowman(4));\n        System.out.println(new Snowman(2, \"pine cone\"));\n    }\n}\n","solution":"// ==== Snowman.java ====\npublic class Snowman {\n    private int balls;\n    private String nose;\n\n    public Snowman() {\n        this.balls = 3;\n        this.nose = \"carrot\";\n    }\n\n    public Snowman(int balls) {\n        this.balls = balls;\n        this.nose = \"carrot\";\n    }\n\n    public Snowman(int balls, String nose) {\n        this.balls = balls;\n        this.nose = nose;\n    }\n\n    public String toString() {\n        return this.balls + \" balls, \" + this.nose + \" nose\";\n    }\n}\n\n// ==== Main.java ====\npublic class Main {\n    public static void main(String[] args) {\n        System.out.println(new Snowman());\n        System.out.println(new Snowman(4));\n        System.out.println(new Snowman(2, \"pine cone\"));\n    }\n}\n","hints":["Three constructors, all called `Snowman`, with different parameters: `public Snowman()`, `public Snowman(int balls)` and `public Snowman(int balls, String nose)`.","Each one sets both instance variables. Where a value isn't given, it uses the default: 3 for the balls, `\"carrot\"` for the nose."],"tests":[{"name":"Test 1","stdin":"","call":"System.out.println(new Snowman());\nSystem.out.println(new Snowman(4));\nSystem.out.println(new Snowman(2, \"pine cone\"));\n","expect":"3 balls, carrot nose\n4 balls, carrot nose\n2 balls, pine cone nose","hidden":false},{"name":"Test 2","stdin":"","call":"System.out.println(new Snowman(5, \"button\"));\nSystem.out.println(new Snowman(6));\n","expect":"5 balls, button nose\n6 balls, carrot nose","hidden":true},{"name":"Test 3","stdin":"","call":"Snowman a = new Snowman(2);\nSnowman b = new Snowman();\nSystem.out.println(b);\nSystem.out.println(a);\n","expect":"3 balls, carrot nose\n2 balls, carrot nose","hidden":true}],"require":[],"forbid":[]},{"task":"What does this program print? `Label` has three constructors. Look at the type of each value given to `new`.\n","kind":"predict","seed":"public class Main {\n    public static void main(String[] args) {\n        Label a = new Label(\"Spices\");\n        Label b = new Label(7);\n        Label c = new Label();\n        Label d = new Label(\"7\");\n        System.out.println(a);\n        System.out.println(b);\n        System.out.println(c);\n        System.out.println(d);\n    }\n}\n// ==== Label.java ====\npublic class Label {\n    private String text;\n\n    public Label() {\n        this.text = \"blank\";\n    }\n\n    public Label(String text) {\n        this.text = text;\n    }\n\n    public Label(int number) {\n        this.text = \"No. \" + number;\n    }\n\n    public String toString() {\n        return \"[\" + this.text + \"]\";\n    }\n}\n","solution":"public class Main {\n    public static void main(String[] args) {\n        Label a = new Label(\"Spices\");\n        Label b = new Label(7);\n        Label c = new Label();\n        Label d = new Label(\"7\");\n        System.out.println(a);\n        System.out.println(b);\n        System.out.println(c);\n        System.out.println(d);\n    }\n}\n// ==== Label.java ====\npublic class Label {\n    private String text;\n\n    public Label() {\n        this.text = \"blank\";\n    }\n\n    public Label(String text) {\n        this.text = text;\n    }\n\n    public Label(int number) {\n        this.text = \"No. \" + number;\n    }\n\n    public String toString() {\n        return \"[\" + this.text + \"]\";\n    }\n}\n","hints":["`new Label(7)` gives an int, so it runs `Label(int number)`. `new Label()` gives nothing, so it runs the constructor without parameters.","`\"7\"` is in quotes, so it's a String, even though it looks like a number. It runs `Label(String text)`."],"tests":[{"name":"Output","stdin":"","expect":"[Spices]\n[No. 7]\n[blank]\n[7]","hidden":false}],"require":[],"forbid":[],"lines":["[Spices]","[No. 7]","[blank]","[7]"]}]}