{"id":"inheritance-object","slug":"object","title":"Every class inherits from Object","text":"Since module 17 you've written classes of your own, and some things worked without your writing them. Module 18 noted that `println` can print an object whose class has no `toString`, module 23 called `equals` on objects whose class had no `equals` yet, and module 32 said that every object has a `hashCode`. Where do those methods come from?\n\nJava has a class called `Object`. It's in `java.lang`, like `String`, so it needs no import. Every class **inherits** from Object: it gets Object's methods, as if they were written in the class itself. This module is about inheritance, and a class of yours can inherit from another class of yours too, not only from Object.\n\n### What Object gives every class\n\nA museum keeps a record of each exhibit: its name and the year it was made. This `Exhibit` class has a constructor and nothing else, yet the program calls four methods on it:\n\n```java\npublic class Main {\n    public static void main(String[] args) {\n        Exhibit vase = new Exhibit(\"Blue vase\", 1720);\n        Exhibit copy = new Exhibit(\"Blue vase\", 1720);\n        System.out.println(vase.getClass().getName());\n        System.out.println(vase.equals(copy));\n        System.out.println(vase.equals(vase));\n        System.out.println(vase.hashCode() == vase.hashCode());\n        String text = vase.toString();\n        System.out.println(text.startsWith(\"Exhibit@\"));\n    }\n}\n// ==== Exhibit.java ====\npublic class Exhibit {\n    private String name;\n    private int year;\n\n    public Exhibit(String name, int year) {\n        this.name = name;\n        this.year = year;\n    }\n}\n```\n\n```output\nExhibit\nfalse\ntrue\ntrue\ntrue\n```\n\nAll four methods come from Object:\n\n- `getClass().getName()` gives the name of the object's class. It's the same on every run.\n- Object's `equals` does the same as `==`: it's `true` only for the very same object (module 23). `vase` and `copy` have the same values, but they're two objects.\n- Object's `hashCode` gives a number for the object. It stays the same while the program runs, but it can change from one run to the next (module 32).\n- Object's `toString` gives the class name, an `@` and the hash code written in hexadecimal (base 16, with the digits 0 to 9 and the letters a to f), something like `Exhibit@1b6d3586`. The hash code changes from run to run, so this course never prints that text: the program above only checks how it starts.\n\n### Your own methods replace Object's\n\nWhen a class writes a method with the same header as one of Object's, the class's own method is used instead of Object's. That's what your `toString` (module 18), `equals` (module 23) and `hashCode` (module 32) have done all along: each one replaced Object's version. Step 4 gives this a name, **overriding**.\n\n```java\nimport java.util.ArrayList;\n\npublic class Main {\n    public static void main(String[] args) {\n        Exhibit vase = new Exhibit(\"Blue vase\", 1720);\n        Exhibit copy = new Exhibit(\"Blue vase\", 1720);\n        System.out.println(vase);\n        System.out.println(vase.equals(copy));\n\n        ArrayList<Exhibit> hall = new ArrayList<>();\n        hall.add(vase);\n        hall.add(new Exhibit(\"Iron helmet\", 1450));\n        System.out.println(hall);\n        System.out.println(\"Next up: \" + hall.get(1));\n        System.out.println(hall.contains(new Exhibit(\"Iron helmet\", 1450)));\n    }\n}\n// ==== Exhibit.java ====\nimport java.util.Objects;\n\npublic class Exhibit {\n    private String name;\n    private int year;\n\n    public Exhibit(String name, int year) {\n        this.name = name;\n        this.year = year;\n    }\n\n    public boolean equals(Object compared) {\n        if (this == compared) {\n            return true;\n        }\n        if (!(compared instanceof Exhibit)) {\n            return false;\n        }\n        Exhibit other = (Exhibit) compared;\n        return this.name.equals(other.name) && this.year == other.year;\n    }\n\n    public int hashCode() {\n        return Objects.hash(this.name, this.year);\n    }\n\n    public String toString() {\n        return this.name + \" (\" + this.year + \")\";\n    }\n}\n```\n\n```output\nBlue vase (1720)\ntrue\n[Blue vase (1720), Iron helmet (1450)]\nNext up: Iron helmet (1450)\ntrue\n```\n\n- `println(vase)`, the way a list prints itself, and `+` with a String all call the object's `toString`, and now that's Exhibit's own.\n- The list's `contains` calls `equals`, and now that's Exhibit's own too.\n- The name, the parameter types and the return type must be Object's, and the method must stay public: `public String toString()`, `public boolean equals(Object compared)` and `public int hashCode()`. (The parameter's name can be anything, as module 23 said; Object's own is `obj`.) That's why `equals` takes an `Object`: Object's `equals` takes one, since any object may be compared with any other. A method `equals(Exhibit compared)` would be a second method next to Object's (overloading, module 21), and lists and maps would go on calling Object's.\n- Object's other methods, such as `getClass`, stay as they are.\n\n### Inheriting, in one word\n\nA class that doesn't say which class it inherits from inherits from Object. So these two headers mean the same:\n\n```java\npublic class Exhibit {\n```\n\n```java\npublic class Exhibit extends Object {\n```\n\nYou'll hardly ever see the second one written out, but it shows the word that the next step is about: `extends`.\n","task":"A museum stores fossils in drawers. `Fossil` has its own `toString`, but no `equals`. What does this program print?\n","kind":"predict","seed":"import java.util.ArrayList;\n\npublic class Main {\n    public static void main(String[] args) {\n        Fossil tooth = new Fossil(\"Shark tooth\", 15);\n        Fossil other = new Fossil(\"Shark tooth\", 15);\n        ArrayList<Fossil> drawer = new ArrayList<>();\n        drawer.add(tooth);\n        System.out.println(tooth);\n        System.out.println(tooth.equals(other));\n        System.out.println(drawer.contains(other));\n        System.out.println(drawer.contains(tooth));\n        System.out.println(other.getClass().getName());\n    }\n}\n// ==== Fossil.java ====\npublic class Fossil {\n    private String name;\n    private int millionYears;\n\n    public Fossil(String name, int millionYears) {\n        this.name = name;\n        this.millionYears = millionYears;\n    }\n\n    public String toString() {\n        return this.name + \", \" + this.millionYears + \" million years old\";\n    }\n}\n","solution":"import java.util.ArrayList;\n\npublic class Main {\n    public static void main(String[] args) {\n        Fossil tooth = new Fossil(\"Shark tooth\", 15);\n        Fossil other = new Fossil(\"Shark tooth\", 15);\n        ArrayList<Fossil> drawer = new ArrayList<>();\n        drawer.add(tooth);\n        System.out.println(tooth);\n        System.out.println(tooth.equals(other));\n        System.out.println(drawer.contains(other));\n        System.out.println(drawer.contains(tooth));\n        System.out.println(other.getClass().getName());\n    }\n}\n// ==== Fossil.java ====\npublic class Fossil {\n    private String name;\n    private int millionYears;\n\n    public Fossil(String name, int millionYears) {\n        this.name = name;\n        this.millionYears = millionYears;\n    }\n\n    public String toString() {\n        return this.name + \", \" + this.millionYears + \" million years old\";\n    }\n}\n","hints":["`println(tooth)` calls Fossil's own `toString`. `getClass().getName()` gives the class's name.","Fossil has no `equals` of its own, so it has Object's, which is the same as `==`. `tooth` and `other` are two different objects, and `contains` compares with `equals`."],"tests":[{"name":"Output","stdin":"","expect":"Shark tooth, 15 million years old\nfalse\nfalse\ntrue\nFossil","hidden":false}],"require":[],"forbid":[],"lines":["Shark tooth, 15 million years old","false","false","true","Fossil"],"more":[{"task":"A museum's `Painting` has a title, an artist and a year. Printing one now shows Object's `toString`: `Painting@` and a hash code. In `Painting.java`, write Painting's own `toString`, so that a painting shows as `Harbor at Dawn by Mina Park (1911)`. The check prints a painting, a list of paintings, and a painting after other text:\n\n```java\nPainting dawn = new Painting(\"Harbor at Dawn\", \"Mina Park\", 1911);\nSystem.out.println(dawn);\nArrayList<Painting> wall = new ArrayList<>();\nwall.add(dawn);\nwall.add(new Painting(\"Red Kite\", \"Tomas Ek\", 1958));\nSystem.out.println(wall);\nSystem.out.println(\"On loan: \" + wall.get(1));\n```\n\nand expects:\n\n```\nHarbor at Dawn by Mina Park (1911)\n[Harbor at Dawn by Mina Park (1911), Red Kite by Tomas Ek (1958)]\nOn loan: Red Kite by Tomas Ek (1958)\n```\n","kind":"code","seed":"// ==== Painting.java ====\npublic class Painting {\n    private String title;\n    private String artist;\n    private int year;\n\n    public Painting(String title, String artist, int year) {\n        this.title = title;\n        this.artist = artist;\n        this.year = year;\n    }\n\n    // Write the toString method here.\n}\n\n// ==== Main.java ====\nimport java.util.ArrayList;\n\npublic class Main {\n    public static void main(String[] args) {\n        Painting dawn = new Painting(\"Harbor at Dawn\", \"Mina Park\", 1911);\n        System.out.println(dawn);\n        ArrayList<Painting> wall = new ArrayList<>();\n        wall.add(dawn);\n        wall.add(new Painting(\"Red Kite\", \"Tomas Ek\", 1958));\n        System.out.println(wall);\n        System.out.println(\"On loan: \" + wall.get(1));\n    }\n}\n","solution":"// ==== Painting.java ====\npublic class Painting {\n    private String title;\n    private String artist;\n    private int year;\n\n    public Painting(String title, String artist, int year) {\n        this.title = title;\n        this.artist = artist;\n        this.year = year;\n    }\n\n    public String toString() {\n        return this.title + \" by \" + this.artist + \" (\" + this.year + \")\";\n    }\n}\n\n// ==== Main.java ====\nimport java.util.ArrayList;\n\npublic class Main {\n    public static void main(String[] args) {\n        Painting dawn = new Painting(\"Harbor at Dawn\", \"Mina Park\", 1911);\n        System.out.println(dawn);\n        ArrayList<Painting> wall = new ArrayList<>();\n        wall.add(dawn);\n        wall.add(new Painting(\"Red Kite\", \"Tomas Ek\", 1958));\n        System.out.println(wall);\n        System.out.println(\"On loan: \" + wall.get(1));\n    }\n}\n","hints":["The header must be exactly Object's: `public String toString() {`. The method returns the text instead of printing it.","`return this.title + \" by \" + this.artist + \" (\" + this.year + \")\";`. The list and the `+` both call the same method."],"tests":[{"name":"Test 1","stdin":"","call":"Painting dawn = new Painting(\"Harbor at Dawn\", \"Mina Park\", 1911);\nSystem.out.println(dawn);\nArrayList<Painting> wall = new ArrayList<>();\nwall.add(dawn);\nwall.add(new Painting(\"Red Kite\", \"Tomas Ek\", 1958));\nSystem.out.println(wall);\nSystem.out.println(\"On loan: \" + wall.get(1));\n","expect":"Harbor at Dawn by Mina Park (1911)\n[Harbor at Dawn by Mina Park (1911), Red Kite by Tomas Ek (1958)]\nOn loan: Red Kite by Tomas Ek (1958)","hidden":false},{"name":"Test 2","stdin":"","call":"Painting study = new Painting(\"Study in Gray\", \"Ada Brandt\", 1874);\nString caption = \"Room 3: \" + study;\nSystem.out.println(caption);\nSystem.out.println(study.toString().length());\n","expect":"Room 3: Study in Gray by Ada Brandt (1874)\n34","hidden":true},{"name":"Test 3","stdin":"","call":"ArrayList<Painting> empty = new ArrayList<>();\nSystem.out.println(empty);\nempty.add(new Painting(\"Snow\", \"Kai Lund\", 2001));\nSystem.out.println(empty);\n","expect":"[]\n[Snow by Kai Lund (2001)]","hidden":true}],"require":[{"pattern":"\\bpublic\\s+String\\s+toString\\s*\\(\\s*\\)","message":"Write the header exactly as `public String toString()`, so that it replaces Object's."}],"forbid":[]},{"task":"A display case holds minerals, and `contains` and `indexOf` should find a mineral with the same name and hardness. Fill in the blank, a type, so that `equals` replaces Object's.\n","kind":"fill","seed":"import java.util.ArrayList;\n\npublic class Main {\n    public static void main(String[] args) {\n        ArrayList<Mineral> display = new ArrayList<>();\n        display.add(new Mineral(\"Quartz\", 7));\n        display.add(new Mineral(\"Talc\", 1));\n        System.out.println(display.contains(new Mineral(\"Talc\", 1)));\n        System.out.println(display.indexOf(new Mineral(\"Quartz\", 7)));\n    }\n}\n// ==== Mineral.java ====\nimport java.util.Objects;\n\npublic class Mineral {\n    private String name;\n    private int hardness;\n\n    public Mineral(String name, int hardness) {\n        this.name = name;\n        this.hardness = hardness;\n    }\n\n    public boolean equals([[Object]] compared) {\n        if (this == compared) {\n            return true;\n        }\n        if (!(compared instanceof Mineral)) {\n            return false;\n        }\n        Mineral other = (Mineral) compared;\n        return this.name.equals(other.name) && this.hardness == other.hardness;\n    }\n\n    public int hashCode() {\n        return Objects.hash(this.name, this.hardness);\n    }\n}\n","solution":"import java.util.ArrayList;\n\npublic class Main {\n    public static void main(String[] args) {\n        ArrayList<Mineral> display = new ArrayList<>();\n        display.add(new Mineral(\"Quartz\", 7));\n        display.add(new Mineral(\"Talc\", 1));\n        System.out.println(display.contains(new Mineral(\"Talc\", 1)));\n        System.out.println(display.indexOf(new Mineral(\"Quartz\", 7)));\n    }\n}\n// ==== Mineral.java ====\nimport java.util.Objects;\n\npublic class Mineral {\n    private String name;\n    private int hardness;\n\n    public Mineral(String name, int hardness) {\n        this.name = name;\n        this.hardness = hardness;\n    }\n\n    public boolean equals(Object compared) {\n        if (this == compared) {\n            return true;\n        }\n        if (!(compared instanceof Mineral)) {\n            return false;\n        }\n        Mineral other = (Mineral) compared;\n        return this.name.equals(other.name) && this.hardness == other.hardness;\n    }\n\n    public int hashCode() {\n        return Objects.hash(this.name, this.hardness);\n    }\n}\n","hints":["The method must have the same header as Object's `equals`, and Object's `equals` can be given any object at all.","The parameter's type is `Object`. With `Mineral` there, the program still compiles, but it's a second method next to Object's, and `contains` goes on calling Object's."],"tests":[{"name":"Output","stdin":"","expect":"true\n0","hidden":false}],"require":[],"forbid":[]}]}