Java 我能';t调用子类中定义的方法

Java 我能';t调用子类中定义的方法,java,Java,我有两门课: 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

我有两门课:

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 program {
    
    public static void main (String [] args) {
    
        Animal hum = new Human("bob", 1);
        
        System.out.println(hum);
        //hum.talking();
        
    }

}


主程序的输出为wk05。Human@7f690630. 那么为什么我不能在主程序中执行“哼,说话”?我对继承的理解是,子类可以调用父类中定义的方法以及子类中定义的方法表示对
动物
超类的嗡嗡声引用,该超类没有
说话()的定义
,对象是

在编译时,将考虑引用而不是对象。对象在运行时使用。因此,如果您想调用
talking()
,您需要:

1)创建对人类类的引用 这里引用的也是
Human
类,因此它在编译时定义了
talking()
方法

Human hum = new Human("bob", 1);
hum.talking();
2)向人类投射对象(仅用于理解类型投射) 当我们强制转换对象时,我们显式地告诉编译器引用定义的对象。所以可以参考

Animal hum = new Human("bob", 1);
((Human) hum).talking();
背后的原因是,假设您还有一个类
SuperHuman
,它也扩展了
Animal
类,而该类没有
talking()
方法,那么编译器将如何知道引用
hum
将引用
超人

假设在初始化过程中,我们做了类似于
animalhum=newhuman(“bob”,1)和之后的代码中,
hum
更新为
hum=SuperHuman(“sup”,10)。这就是编译时引用和运行时引用对象的原因。

该错误是编译错误;编译器并不关心对象类型实际上是什么(或可能是什么),它只关心它声明为什么

而且,我几乎可以肯定你的方法不应该是静态的

如果你想做一些你正在探索的事情,你必须把方法抽象出来,要么作为一个接口,要么作为一个抽象方法。例如:

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");
    }
}
如前所述,您必须创建对
人类
的引用,或将
动物
转换为
人类
。但如果Animal是一个接口或抽象类(我并不特别喜欢这样做),并且公开了一个所有派生类都必须实现的方法,那么继承就更有意义了

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");
    }
}
主要的

public class Program {

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

如果你想展示多态性和/或继承性,你不想在一个方法上使用
static
。您必须声明(或强制转换)
hum
为type
Human
,否则它将不允许您进行调用。@markspace但如果我执行“hum.eating()”,为什么我可以运行此代码。没有发生错误,因为
eating()
是类型
Animal
上的一个方法,这是您声明的。成员的可见性基于声明的类型,而不是实际的运行时类型。
public class Program {

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