How to call the overridden method of a superclass?
How can I call the eat and drink method of the Animal
class with the myAnimal
instance in the code?
public class Animal {
public void eat() {
System.out.println("Animal Eats");
}
public void drink() {
System.out.println("Animal Drinks");
}
}
public class Cat extends Animal {
@Override
public void eat() {
System.out.println("Cat Eats");
}
@Override
public void drink() {
System.out.println("Cat Drinks");
}
public static void main(String[] args) {
Cat myCat = new Cat();
myCat.eat();
myCat.drink();
Animal myAnimal = myCat;
myAnimal.eat();
myAnimal.drink();
}
}
Output that I am getting:
Cat Eats
Cat Drinks
Cat Eats
Cat Drinks
This is my expected output:
Cat Eats
Cat Drinks
Animal Eats
Animal Drinks
You cannot do what you want. The way polymorphism works is by doing what you are seeing.
Basically a cat always knows it is a cat and will always behave like a cat regardless of if you treat is as a Cat, Felis, Felinae, Felidae, Feliformia, Carnivora, Theria, Mammalia, Vertebrata, Chordata, Eumetazoa, Animalia, Animal, Object, or anything else :-)
Here you will have an option to choose which method do you want to invoke:
public class Cat extends Animal {
public void superEat() {
super.eat();
}
public void superDrink() {
super.drink();
}
@Override
public void eat() {
System.out.println("Cat Eats");
}
@Override
public void drink() {
System.out.println("Cat Drinks");
}
}
This line:
Animal myAnimal = myCat;
assigns the variable myAnimal
to the object myCat
, which you've created before. So when you call myAnimal.eat()
after that, you're actually calling the method of the original myCat object, which outputs Cat Eats
.
If you want to output Animal Eats
, you'll have to assign an Animal
instance to a variable. So if you would do this instead:
Animal myAnimal = new Animal()
the variable myAnimal will be an instance of Animal
, and thus will overwrite the previous assignment to Cat
.
If you will call myAnimal.eat()
after this, you're actually calling the eat()
method of the Animal
instance you've created, which will output Animal Eats
.
Concluding: your code should read:
public class Cat extends Animal {
@Override
public void eat() {
System.out.println("Cat Eats");
}
@Override
public void drink() {
System.out.println("Cat Drinks");
}
public static void main(String[] args) {
Cat myCat = new Cat();
myCat.eat();
myCat.drink();
Animal myAnimal = new Animal();
myAnimal.eat();
myAnimal.drink();
}
}
- Access to static fields, instance fields and static methods depends on the class of reference variable and not the actual object to which the variable points to.
- Remember that member variables are shadowed, not overridden.
-
This is opposite of what happens in the case of instance methods.
In case of instance methods the method of the actual class of the object is called.class ABCD { int x = 10; static int y = 20; public String getName() { return "ABCD"; } } class MNOP extends ABCD { int x = 30; static int y = 40; public String getName() { return "MNOP"; } } public static void main(String[] args) { System.out.println(new MNOP().x + ", " + new MNOP().y); ABCD a = new MNOP(); System.out.println(a.x); // 10 System.out.println(a.y); // 20 System.out.println(a.getName()); // MNOP }
In this example although the the object myCat is assigned to an Animal object reference, (Animal myAnimal = myCat
) the Actual object is of type Cat
and it behaves as it's a cat.
Hope this helps.