简体   繁体   中英

I can't invoke the method defined in the subclass

I have 2 classes:

public class Animal {
    
    protected String name;
    int age;
    
    
    public Animal(String name, int age) {
        // TODO Auto-generated constructor stub
    
        this.name = name;
        this.age = age;
    }
    
    public static void eating() {
        System.out.println("eating");
    }
}

public class Human extends Animal{

    public Human(String name, int age) {
        // TODO Auto-generated constructor stub
        super(name, age);
    }
    
    
    public static void talking() {
        System.out.println("Talk");
    }
}

main program:

public class program {
    
    public static void main (String [] args) {
    
        Animal hum = new Human("bob", 1);
        
        System.out.println(hum);
        //hum.talking();
        
    }

}

The output of the main program is wk05.Human@7f690630 . So why I can't do "hum.talking" in the main program? My understanding of inheritance is that the subclass can invoke the methods defined in the parent class as well as the method defined in the subclass.

Here in your program Animal hum = new Human("bob", 1); means hum reference to Animal super class which does not have definition of talking() and object is Human .

At compile time reference is considered rather than the object. Object is used at runtime. So if you want to call talking() you would need to:

1) Create reference to Human class Here the reference is also to Human class so it has the definition of talking() method at compile time.

Human hum = new Human("bob", 1);
hum.talking();

2) Cast object to Human (only for understanding the type-casting) When we cast the object we explicitly tell the compiler to refer the defined object. So it can refer that.

Animal hum = new Human("bob", 1);
((Human) hum).talking();

Reason behind is that let's say you have one more class SuperHuman which also extends Animal class and that class doesn't have talking() method then how the compiler would be knowing that reference hum will be referring Human or SuperHuman ?

And let's say during initialization you have we have done like Animal hum = new Human("bob", 1); and later in code the hum is updated to hum = SuperHuman("sup", 10); . That's the reason compile time reference is referred and Object is referred at runtime.

The error is a compile error; the compiler doesn't care what the object type actually is (or could be), it only cares about what it’s declared as.

Also, I'm almost certain your methods should not be static.

If you were to do something like what you're exploring, you have to abstract out the method, either as an interface or an abstract method. For example:

class abstract Animal {
    abstract void communicate();
}

class Dog extends Animal {
    void communicate() {
        System.out.println("bark");
    }
}

class Human extends Animal {
    void communicate() {
        System.out.println("talk");
    }
}

As Gaurav says you have to create a reference to Human or cast Animal to Human . But inheritance would make more sense if Animal were an interface or an abstract class (What I don't particularly like to do) and exposed a method in which all derived classes should have to implement.

public interface Animal {

    String getName();
    int getAge();
    void blab();
}

public class Human implements Animal {

    private String name;
    private int age;

    Human(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() { return name; }
    
    public int getAge() { return age; }

    public void blab() {
        System.out.println("Talk");
    }
}

And the main

public class Program {

    public static void main(String[] args) {
        Animal animal = new Human("Bob", 1);
        animal.blab();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM