public class Inheritance { public static void main(String[] args) { Parent justParent = new Parent(); Parent childDisguisedAsParent = new Child("Bob"); Child actuallyAChild = new Child("Alice"); System.out.println("=== Just Parent ==="); System.out.println("Accessing 'name' property: " + justParent.name); System.out.println("Accessing 'familyName' property: " + justParent.familyName); System.out.println("Calling 'who()' method: " + justParent.who()); System.out.println(); System.out.println("=== Child Disguised As Parent ==="); // Accesses parent's name property due to being of type (Parent) System.out.println("Accessing 'name' property: " + childDisguisedAsParent.name); // Down-casting to (Child) allows us to access the child's name property System.out.println("Accessing 'name' property (Down Cast): " + ((Child) childDisguisedAsParent).name); // Accesses parent's name property System.out.println("Accessing 'familyName' property: " + childDisguisedAsParent.familyName); // Call's the method defined in Child despite being of type (Parent), because the real type is (Child) which overrides 'who()' System.out.println("Calling 'who()' method: " + childDisguisedAsParent.who()); // 'parentsWho()' doesn't exist in (Parent), so down-casting is needed to be able to call the method System.out.println("Calling 'parentsWho()' method (MUST Down Cast): " + ((Child)childDisguisedAsParent).parentsWho()); System.out.println(); System.out.println("=== Actually A Child ==="); System.out.println("Accessing 'name' property: " + actuallyAChild.name); System.out.println("Accessing 'name' property (Up Cast): " + ((Parent) actuallyAChild).name); System.out.println("Accessing 'familyName' property: " + actuallyAChild.familyName); System.out.println("Calling 'who()' method: " + actuallyAChild.who()); System.out.println("Calling 'parentsWho()' method: " + ((Child)childDisguisedAsParent).parentsWho()); System.out.println(); } public static class Parent { public final String name = "dad"; public final String familyName = "Kong"; public String who() { return "I am the parent! My name is " + name; } } public static class Child extends Parent { public final String name; public Child(String name) { super(); this.name = name; } public String who() { return "I am the child! My name is " + name; } public String parentsWho() { return super.who(); } }}