How to call the overridden method of a superclass? - java
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.
You can create constructor for class Animal, that takes another Animas as parameter, and creates new instance based on provided one.
public class Animal {
//some common animal's properties
private int weight;
private int age;
public Animal() {
// empty.
}
public Animal(final Animal otherAnimal) {
this.weight = otherAnimal.getWeight();
this.age = otherAnimal.getAge();
}
public void eat() {
System.out.println("Animal Eats");
}
public void drink() {
System.out.println("Animal Drinks");
}
// setters and getters.
}
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();
// note: myAnimal is not a Cat, it's just an Animal.
Animal myAnimal = new Animal(myCat);
myAnimal.eat();
myAnimal.drink();
}
}
Few suggestions :
Don't pass child class reference to super class and except super class method has to be invoked for overridden method. Call super class methods from super class instance.
Animal myAnimal = new Animal();
myAnimal.eat();
If you want to call super class method from child class, explicitly call super class method name with super.methodName();
public void eat() {
super.eat();
System.out.println("Cat Eats");
}
Don't override super class method in child class. Always super class method is invoked.
If you make methods in each class static, it should work.
public class Animal {
public static void eat() {
System.out.println("Animal Eats");
}
public static void drink() {
System.out.println("Animal Drinks");
}
}
public class Cat extends Animal {
#Override
public static void eat() {
System.out.println("Cat Eats");
}
#Override
public static 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();
}
}
The above code will give the following output
Cat Eats
Cat Drinks
Animal Eats
Animal Drinks
You can achieve what you want using the super keyword, which allows to access the overridden method.
public class Animal {
public void eat() {
System.out.println("Animal Eats");
}
public void drink() {
System.out.println("Animal Drinks");
}
}
public class Cat extends Animal {
public void eat() {
System.out.println("Cat Eats");
}
public void drink() {
System.out.println("Cat Drinks");
}
public void printMessage(){
super.eat();
super.drink();
}
public static void main(String[] args) {
Cat myCat = new Cat();
myCat.eat();
myCat.drink();
myCat.printMessage();
}
}
Please don't vote on this answer... you can vote on the other one :-) This is a bad answer, but shows how you would do what you are trying to do... poorly.
public class Main
{
public static void main(final String[] argv)
{
Child child;
Parent parent;
child = new Child();
parent = child;
child.a();
parent.a();
child.otherA();
parent.otherA();
}
}
class Parent
{
public void a()
{
System.out.println("Parent.a()");
}
public void otherA()
{
// doesn't matter what goes here... really should be abstract
}
}
class Child
extends Parent
{
#Override
public void a()
{
System.out.println("Child.a()");
}
#Override
public void otherA()
{
super.a();
}
}
public class Main {
public static void main(String[] args) {
Cat myCat = new Cat();
myCat.eat();
myCat.drink();
Animal myAnimal = new Animal();
myAnimal.eat();
myAnimal.drink();
}
}
public class Animal {
public void eat(){
System.out.println("Animal eat() called");
}
public void drink(){
System.out.println("Animal drink() called");
}
}
public class Cat extends Animal {
#Override
public void eat() {
System.out.println("Cat eat() called");
}
#Override
public void drink() {
System.out.println("cat drink() called");
}
}
OUTPUT:
Cat eat() called
cat drink() called
Animal eat() called
Animal drink() called
You need to create an object of the super class Animal OR another option is to use the keyword super in the child class methods e.g., super.eat() or super.drink()
Cat can't stop being a cat, even if it is an animal. Cat will eat and cat will drink in a cat's way. It might be similar to what an Animal does, which is why it overrides the method. If you want it to do what the animal does by default, don't override. You could probably do some weird stuff with reflection and make separate methods that access the parent methods such as:
public void superDrink() {
Animal.class.getMethod("drink").invoke();
}
but that might be overkill don't you think?
Of course that probably wouldn't work since it's not static.
You can do what you want with a few minor changes to your code. Naturally the methods of the Animal class have been overriden and you cannot simply access them by changing the reference type. Instead, you could slightly change the definition of the eat and drink functions as follows.
class Animal{
public void eat(boolean randomBoolean){
System.out.println("Animal eats");
}
public void drink(boolean randomBoolean){
System.out.println("Animal drinks");
}
}
class Cat extends Animal{
public void eat(boolean wantOverriden){
if(wantOverriden){
boolean randomBooleanValue=true|false;
super.eat(randomBooleanValue);
}
else{
System.out.println("Cat eats");
}
}
public void drink(boolean wantOverriden){
if(wantOverriden){
boolean randomBooleanValue=true|false;
super.drink(randomBooleanValue);
}
else{
System.out.println("Cat drinks");
}
}
}
Now you should be able to access the overriden methods of the Animal class through the Cat class object by simply passing in a boolean value indicating if you want to do so ex:
Cat c=new Cat();
c.eat(false); //Indicating that you dont want to access the overriden method
c.drink(false); //Indicating that you dont want to access the overriden method
c.eat(true); //Indicating that you want to access the overriden method
c.drink(true); //Indicating that you want to access the overriden method
Related
Conditionally instantiate a different class
Assume that I've the following classes: 1) Animal class, a base class public abstract class Animal { public abstract void Hello(); } 2) Dog class, extends from Animal class public class Dog extends Animal { #Override public void Hello() { System.out.println("I'm Dog"); } } 3) Wolf class, extends from Animal class public class Wolf extends Animal { #Override public void Hello() { System.out.println("I'm Wolf"); } } In the Dog class's constructor or newInstance method, is there a way to switch/turn itself into a Wolf class under a certain condition, say during full moon? So, basically, if the caller does something like below, the variable "a" will be a Wolf object during full moon, instead of a Dog object. Animal a = (Animal) Class.forName("Dog").newInstance();
You could use a wrapper for Animal to delegate to the actual Animal you wish to track and; then include in the delegator wrapper a method to swap delegates based on the class name of the Animal you want. Here is an example class: public abstract class Animal { public abstract String hello(); static class Dog extends Animal { #Override public String hello() { return "I'm Dog"; } } static class Wolf extends Animal { #Override public String hello() { return "I'm Wolf"; } } static class AnimalWrapper extends Animal { private Animal delegate = new Dog(); public void delegateTo(String className) throws Exception { this.delegate = (Animal) Class.forName(className).newInstance(); } #Override public String hello() { return delegate.hello(); } } public static void main(String[] args) throws Exception { AnimalWrapper animal = new AnimalWrapper(); System.out.println("Animal says: " + animal.hello()); animal.delegateTo(Wolf.class.getName()); System.out.println("Animal says: " + animal.hello()); animal.delegateTo(Dog.class.getName()); System.out.println("Animal says: " + animal.hello()); } } Complete code on GitHub
You cannot do that. It looks like you need something like factory (search for factory design pattern) that will be responsible for creating instance of class you need.
Can i call child class method using parent object?
I have created base class animal and child class as cat. In main, I want to create obj of PARENT class and call the method of child class. So, is it possible or not? I have also used instanceOf to just check relationship public class Animal { public void eats() { System.out.println("Animal Eats"); } } public class Cat extends Animal { public void walks() { System.out.println("Cat Walks"); } } public class AnimalMain { public static void main(String args[]) { Animal a=new Animal(); display(a); } public static void display(Animal a) { a.eats(); if(a instanceof Cat) ((Cat)a).walks(); } }
Your code should work fine. The if condition will result in false, so your animal will not walk(). Animal animal = new Animal(); This animal will have all the behaviours of Animal, i.e. eat(), but none of the behaviours of the sub-class Cat, i.e. walk(). If you want your animal to have all the behaviours of Animal as well as all the behaviours of Cat, you need to instantiate the Cat class. Animal animal = new Cat(); Now your animal will eat and walk.
Yes, it will. You are changing the type, so it will work.
When call the same method from parent by super word [duplicate]
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.
You can create constructor for class Animal, that takes another Animas as parameter, and creates new instance based on provided one. public class Animal { //some common animal's properties private int weight; private int age; public Animal() { // empty. } public Animal(final Animal otherAnimal) { this.weight = otherAnimal.getWeight(); this.age = otherAnimal.getAge(); } public void eat() { System.out.println("Animal Eats"); } public void drink() { System.out.println("Animal Drinks"); } // setters and getters. } 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(); // note: myAnimal is not a Cat, it's just an Animal. Animal myAnimal = new Animal(myCat); myAnimal.eat(); myAnimal.drink(); } }
Few suggestions : Don't pass child class reference to super class and except super class method has to be invoked for overridden method. Call super class methods from super class instance. Animal myAnimal = new Animal(); myAnimal.eat(); If you want to call super class method from child class, explicitly call super class method name with super.methodName(); public void eat() { super.eat(); System.out.println("Cat Eats"); } Don't override super class method in child class. Always super class method is invoked.
If you make methods in each class static, it should work. public class Animal { public static void eat() { System.out.println("Animal Eats"); } public static void drink() { System.out.println("Animal Drinks"); } } public class Cat extends Animal { #Override public static void eat() { System.out.println("Cat Eats"); } #Override public static 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(); } } The above code will give the following output Cat Eats Cat Drinks Animal Eats Animal Drinks
You can achieve what you want using the super keyword, which allows to access the overridden method. public class Animal { public void eat() { System.out.println("Animal Eats"); } public void drink() { System.out.println("Animal Drinks"); } } public class Cat extends Animal { public void eat() { System.out.println("Cat Eats"); } public void drink() { System.out.println("Cat Drinks"); } public void printMessage(){ super.eat(); super.drink(); } public static void main(String[] args) { Cat myCat = new Cat(); myCat.eat(); myCat.drink(); myCat.printMessage(); } }
Please don't vote on this answer... you can vote on the other one :-) This is a bad answer, but shows how you would do what you are trying to do... poorly. public class Main { public static void main(final String[] argv) { Child child; Parent parent; child = new Child(); parent = child; child.a(); parent.a(); child.otherA(); parent.otherA(); } } class Parent { public void a() { System.out.println("Parent.a()"); } public void otherA() { // doesn't matter what goes here... really should be abstract } } class Child extends Parent { #Override public void a() { System.out.println("Child.a()"); } #Override public void otherA() { super.a(); } }
public class Main { public static void main(String[] args) { Cat myCat = new Cat(); myCat.eat(); myCat.drink(); Animal myAnimal = new Animal(); myAnimal.eat(); myAnimal.drink(); } } public class Animal { public void eat(){ System.out.println("Animal eat() called"); } public void drink(){ System.out.println("Animal drink() called"); } } public class Cat extends Animal { #Override public void eat() { System.out.println("Cat eat() called"); } #Override public void drink() { System.out.println("cat drink() called"); } } OUTPUT: Cat eat() called cat drink() called Animal eat() called Animal drink() called You need to create an object of the super class Animal OR another option is to use the keyword super in the child class methods e.g., super.eat() or super.drink()
Cat can't stop being a cat, even if it is an animal. Cat will eat and cat will drink in a cat's way. It might be similar to what an Animal does, which is why it overrides the method. If you want it to do what the animal does by default, don't override. You could probably do some weird stuff with reflection and make separate methods that access the parent methods such as: public void superDrink() { Animal.class.getMethod("drink").invoke(); } but that might be overkill don't you think? Of course that probably wouldn't work since it's not static.
You can do what you want with a few minor changes to your code. Naturally the methods of the Animal class have been overriden and you cannot simply access them by changing the reference type. Instead, you could slightly change the definition of the eat and drink functions as follows. class Animal{ public void eat(boolean randomBoolean){ System.out.println("Animal eats"); } public void drink(boolean randomBoolean){ System.out.println("Animal drinks"); } } class Cat extends Animal{ public void eat(boolean wantOverriden){ if(wantOverriden){ boolean randomBooleanValue=true|false; super.eat(randomBooleanValue); } else{ System.out.println("Cat eats"); } } public void drink(boolean wantOverriden){ if(wantOverriden){ boolean randomBooleanValue=true|false; super.drink(randomBooleanValue); } else{ System.out.println("Cat drinks"); } } } Now you should be able to access the overriden methods of the Animal class through the Cat class object by simply passing in a boolean value indicating if you want to do so ex: Cat c=new Cat(); c.eat(false); //Indicating that you dont want to access the overriden method c.drink(false); //Indicating that you dont want to access the overriden method c.eat(true); //Indicating that you want to access the overriden method c.drink(true); //Indicating that you want to access the overriden method
If I've cast a subclass as its superclass, and call a method that was overridden in the subclass, does it perform the overridden or original method?
Consider: Dog is a subclass of Animal, and Dog overrides Animal.eat() Animal[] animals = getAllAnimals(); for (int i = 0; i < animals.length; i++) { animals[i].eat(); } If Animal.eat() is overriden by Dog.eat(), which one is called when the method is called from an identifier of type Animal (animals[i]?)
The subclass method will be called. That's the beauty of polymorphism.
The subclass will be the only method call, unless the subclass calls the superclass like this: class Dog { public eat() { super.eat(); } }
The code Animal a = new Dog(); a.eat(); will call Dog's eat method. But beware! If you had class Animal { public void eat(Animal victim) { System.out.println("Just ate a cute " + victim.getClass().getSimpleName()); } } and you have a Cat that defines an additional method: class Cat extends Animal { public void eat(Mouse m) { System.out.println("Grabbed a MOUSE!"); } } and then you use them: Animal cat = new Cat(); Animal mouse = new Mouse(); cat.eat(mouse); This will print "Just ate a cute Mouse", and not "Grabbed a MOUSE!". Why? Because polymorphism only works for the object to the left of the dot in a method invocation.
It'll call the version in the subclass. Inheritance would be pretty useless if you couldn't pass around a subclassed object cast as its superclass and not get the subclassed method!
A sscce /** * #author fpuga http://conocimientoabierto.es * * Inheritance test for http://stackoverflow.com/questions/10722447/ * */ public class InheritanceTest { public static void main(String[] args) { Animal animals[] = new Animal[2]; animals[0] = new Animal(); animals[1] = new Dog(); for (int i = 0; i < animals.length; i++) { animals[i].eat(); if (animals[i] instanceof Dog) { System.out.println("!!Its a dog instance!!"); ((Dog) animals[i]).eat(); } } } private static class Animal { public void eat() { System.out.println("I'm an animal"); } } private static class Dog extends Animal { #Override public void eat() { System.out.println("I'm dog"); } } }
Java abstract class implements interface
I have the following interface and abstract class that implements it: interface Walk { String walk(); } public abstract class Animal implements Walk { abstract String MakeNoise(); } And the following concrete implementations: class Cat extends Animal { String MakeNoise() { return "Meow"; } #Override String walk() { return "cat is walking"; } } class Dog extends Animal { #Override String walk() { return "Dog is walking"; } #Override String MakeNoise() { return "bark"; } } class Human { public void Speak() { System.out.println("...Speaking..."); } } Putting it all together: class MainClass { public static void main(String[] args) { Random randomGen = new Random(); Animal[] zoo = new Animal[4]; zoo[0] = new Cat(); zoo[1] = new Dog(); zoo[2] = new Cat(); zoo[3] = new Cat(); // System.out.println(zoo[ randomGen.nextInt(2)].MakeNoise()); for (Animal animal : zoo) { if (animal instanceof Dog) { Dog jeffrey = (Dog) animal; System.out.println(jeffrey.MakeNoise()); } } } } I get this error "walk() in Cat cannot implement walk() in Walk " . Any ideas? thanks
Methods in interfaces are implicitly public. However, methods in classes are package-visible by default. You cannot reduce the visibility of an overriden method, i.e. you can't do stuff like this: class A { public foo() {} } class B extends A { private foo() {} // No! } class C extends A { foo() {} // No! foo is package-visible, which is lower than public } In your case, the solution is to declare walk() as public in Dog and Cat.
The error eclipse gives is: Cannot reduce the visibility of the inherited method from Walk The method must be public, because it is defined in an interface.
Interface methods must be public. You need to declare walk() as a public method in Cat.
Make String walk() implementations public. That will fix it