难以理解java继承和覆盖的概念

时间:2016-08-07 09:59:03

标签: java inheritance method-overriding

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

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()的输出应该是& #34;动物可以移动"而不是"狗可以走路和奔跑"但这不是案例。任何人都可以帮我这个吗?提前致谢!

4 个答案:

答案 0 :(得分:1)

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

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

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

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

答案 1 :(得分:1)

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

以这种方式思考,所有的狗都是动物,但并非所有的动物都是狗。所有的狗都会吠叫,但不是所有的动物都会吠叫。

答案 2 :(得分:1)

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

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

((Dog) b).bark();

答案 3 :(得分:0)

这段代码错了,因为行b.bark();会给你一个编译错误,因为b只定义为一个动物,它不能叫()。

如果您将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();
    }
}