【问题标题】:Why bark method can not be called为什么不能调用树皮方法
【发布时间】:2015-08-14 22:34:45
【问题描述】:
class Animal{
    void run() {
    }
}
class Dog extends Animal {
    void bark() {
    }
}
class Testing{
    public static void main(String[] args)  {
        Animal d = new Dog();
        d.run();
        d.bark();
    }
}

我正在尝试使用 dog 类的对象调用 bark 方法,该对象的引用存储在 Animal 类变量中。但它向我显示编译时错误。谁能解释一下为什么?

【问题讨论】:

  • 我猜树皮问题来自你的继承tree...

标签: java inheritance


【解决方案1】:

这就是它的工作原理。

当编译器试图检测谁是d.?见。

Animal d

编译器不知道它是如何创建的,看看引用类型。所以,d 是一个Animal

现在参考是AnimalAnimalbark() 方法吗?不。 错误

可能d 内部是Dog,但编译器不知道,编译器也不应该知道,在这种情况下,编译器会翻译你所说的关于d 的内容。这就是您收到错误的原因。

现在你可以说我想让d 充当Dog,因为我知道dDog by,

((Dog) d);

然后拨打bark()

((Dog) d).bark();

因此编译器将d 作为Dog 仅用于此操作。

【讨论】:

  • 那么使用 Animal d = new Dog() 有什么好处呢?只使用 Dog d = new Dog() 不是更好吗?
【解决方案2】:

您只能调用引用类型中定义的方法。也就是说,由于 Animal 类只有一个方法( run() ),因此即使它引用 Dog 对象,您也不能对其调用 bark()。

你做的是upcasting,你可以了解更多关于upcasting和downcastinghere

【讨论】:

    【解决方案3】:

    这是因为您将您的狗存储在Animal 类型的变量中,该变量只能run()。可能有另一种动物Cat 无法bark()

    如果你想让狗bark()那么你需要放入一个Dog类型的变量:

    Dog rolf = new Dog();
    rolf.bark();
    

    【讨论】:

    • 那我如何访问树皮方法?
    • @ManishKumar 我已经扩展了答案。
    【解决方案4】:

    你可以使用显式转换来调用它

    ((Dog)d).bark();
    

    【讨论】:

    • 你应该解释为什么你的代码可以工作,这样操作才能学习
    • 我确实说过显式强制转换,它在 java 文档中有详尽的解释。
    • 看op问题,很明显他没有完全理解继承和多态的概念。在这方面,提供一个技术性的、单一的解决方案对他没有多大帮助。
    【解决方案5】:

    您已将d 声明为Animal

    但是,虽然内部 d 可能是 Dog,但存储为 Animal 将只允许您使用在 Animal 中声明的方法。

    【讨论】:

    • 那我如何访问树皮方法?
    • 您必须在Animal 中声明bark(),或者将d 声明为Dog,如Dog d = new Dog();
    猜你喜欢
    • 2011-12-09
    • 2013-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-02
    • 2015-04-13
    相关资源
    最近更新 更多