polymorphism has two concepts about methods.
method overloading - where you overload/add/has different parameters in your method
ex:
class ClassA { String whoAmI() { return "ClassA"; } } class ClassB extends ClassA{ // you are overloading the method whoAmI from class A String whoAmI(String name) { return "ClassB "+name; } }
method overriding - where you override/change the default function of a method
class ClassA { String whoAmI() { return "ClassA"; } } class ClassB extends ClassA{ // override whoAmI method change function String whoAmI() { //do something int foo = 5 + 10; return "ClassB foo: "+foo; } }
and in your question
class ClassA { String whoAmI() { return "ClassA"; } } class Main { public static void main(String[] args) { Object obj1 = new ClassA(); obj1.whoAmI(); } }
from your code snippet above you are referencing an object ClassA() to an Object WHICH the object does'nt have the whoAmI() method. you're saying that the obj1 is a ClassA() type of object which they have different sets of methods.
Object / ClassA() | method:whoAmI()
referring to the class hierarchy above. the classA() has a method of whoAmI() and the Object has equals(), hashCode(), getClass(), etc...() when you're extending to an Object the super class doesn't inherit the methods inside the child class. In your example since ClassA() is extending Object (super class), Object will not inherit the whoAmI() method but it is the other way around. the ClassA() will inherit the methods inside Object. and if you are referencing your ClassA() to Object and accessing a method inside ClassA() you need to cast your Object to ClassA() to tell the compiler that i am calling a method from ClassA().
EDITED:
in your example the output is not the same because you are giving a reference of ClassB() to ClassA() that overrides the method whoAmI();
and in your List example, ArrayList implements List but the instance variable is A List. refer to "diagram below"
Custom class
Class A Class B extends A method: whoAmI() method override: whoAmI() output: "i am class A" output: "i am new class B" method: fooMethod() output: "my own method"
so when you declare a Class A object you will be using the class a methods,fields etc
ClassA obj = new ClassA();
once you change the reference object to ClassB() you will be now using the ClassB's overriden method/different sets of fields, etc.. but it doesnt mean that you can call fooMethod() easily because remember it is still a ClassA the methods in ClassB inside ClassA will be overriden.
ClassA obj = new ClassB(); // override whoAmI() method changed output
but when you cast the obj to ClassB() it is like you are telling the compiler that this obj is a ClassB() this is when you can use the fooMethod() because the compiler thinks that obj(casted) is a ClassB
((ClassB)obj).fooMethod();
i tried the best way i can to explain this the simplest way i know. cheerioo