【问题标题】:Difficulty with the concept of java inheritance and overriding [duplicate]java继承和覆盖概念的困难[重复]
【发布时间】:2016-08-07 09:59:02
【问题描述】:

超类引用变量可以保存子类对象,但使用该变量您只能访问超类的成员,因此要访问两个类的成员,建议始终为子类创建引用变量。

class Animal {
   public void move() {
      System.out.println("Animals can move");
   }
}

class Dog extends Animal {
   public void move() {
      System.out.println("Dogs can walk and run");
   }
   public void bark() {
      System.out.println("Dogs can bark");
   }
}

public class TestDog {

   public static void main(String args[]) {
      Animal a = new Animal();   // Animal reference and object
      Animal b = new Dog();   // Animal reference but Dog object

      a.move();   // runs the method in Animal class
      b.move();   // runs the method in Dog class
      b.bark();
   }
}

输出:

TestDog.java:26: error: cannot find symbol
  b.bark();
   ^
symbol:   method bark()
location: variable b of type Animal
1 error

我在这里不明白的是为什么对象'b'能够访问 Dog.move() 而不是 Dog.bark() 因为上面提到的语句说它只能访问超类的成员而不是子类。按照这个逻辑,b.move() 的输出应该是“动物可以移动”而不是“狗可以走路和奔跑”。但事实并非如此。有人可以帮我吗?提前致谢!

【问题讨论】:

  • b.bark();是错误的,因为动物不会吠叫。需要向下转换,例如: ((Dog) b).bark();

标签: java inheritance overriding


【解决方案1】:

恭喜 - 你刚刚发现了多态性。


在 Java 中,类是动态绑定的。也就是说,如果您正在调用一个方法,则会调用对象的实现(在您的情况下为 Dog),而不是引用类型的方法(在您的情况下为 Animal)。

这允许覆盖方法并替换或完成它们的实现。


另一方面,您只能访问在您引用的类型中可用的方法,而不是实现类型(在您的情况下为Animal)。要调用实例的方法,您必须将其用作引用类型(在您的情况下为 Dog)。

【讨论】:

  • 知道了!谢谢@Fabian Damken。
【解决方案2】:

在您的问题中,Animal 是一个没有 bark() 方法的父类,因此该方法不会被覆盖。如果您能够从父类访问bark(),而无需声明或定义抽象方法,那么这将违反Polymorphism 原则。

如果您真的想以这种方式访问​​它,那么您可以在您的父级中定义 abstract public void bark(); 或通过像这样的类型转换来访问该方法

((Dog) b).bark();

【讨论】:

    【解决方案3】:

    由于Animal 没有名为bark 的方法,因此无法编译。

    这样想,所有的狗都是动物,但并非所有的动物都是狗。所有的狗都会吠叫,但并非所有的动物都会吠叫。

    【讨论】:

      【解决方案4】:

      这段代码是错误的,b.bark(); 行会给你一个编译器错误,因为 b 只定义为一个 Animal,它不能 bark()。

      如果您将Animal b = new Dog(); 更改为Dog d = new Dog();,它将正常工作。

      你把继承搞混了。狗能做动物能做的事,反之则不行。

      class Animal {
          public void move() {
              System.out.println("Animals can move");
          }
      }
      
      
      
      class Dog extends Animal {
          @Override public void move() {
              System.out.println("Dogs can walk and run");
          }
          public void bark() {
              System.out.println("Dogs can bark");
          }
          public void moveSuper() {
              super.move();
          }
      }
      
      
      
      public class TestDog {
      
          public static void main(final String args[]) {
              final Animal a = new Animal(); // Animal reference and object
              a.move(); // runs the method in Animal class
      
              final Dog d = new Dog(); // Animal reference but Dog object
              d.move(); // runs the method in Dog class
              d.bark();
              d.moveSuper();
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-02-08
        • 2017-04-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多