java 继承和覆盖的概念有困难
Difficulty with the concept of java inheritance and overriding
超类引用变量可以保存子类对象,但使用该变量只能访问超类的成员,因此要访问两者的成员 类 建议始终创建引用变量以子类。
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()因为上面的语句说它可以访问只有超类的成员而不是 subclass.Following 这个逻辑 b.move() 的输出应该是 "Animals can move" 而不是 "Dogs can walk and run"。但这不是 case.Can有人帮我解决这个问题吗?提前致谢!
恭喜 - 您刚刚发现了多态性。
在Java中,类是动态绑定的。也就是说,如果您正在调用一个方法,则会调用对象的实现(在您的情况下为 Dog
),而不是引用类型的方法(在您的情况下为 Animal
)。
这允许覆盖方法并替换或完成它们的实现。
另一方面,您只能访问在您引用的类型中可用的方法,而不能访问实现类型(在您的情况下为 Animal
)。要调用实例的方法,您必须将其用作引用类型(在您的情况下为 Dog
)。
这段代码是错误的,因为行 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();
}
}
这将无法编译,因为 Animal
没有名为 bark
的方法。
这样想,所有的狗都是动物,但是并非所有的动物都是狗。所有的狗都会叫,但不是所有的动物都会叫。
在您的问题中,Animal
是父 class,它没有 bark()
方法,因此不会覆盖该方法。如果您能够在不声明或定义抽象方法的情况下从父 class 访问 bark()
,那么这将违反 Polymorphism 原则。
如果你真的想以这种方式访问它,那么你可以在你的父级中定义一个 abstract public void bark();
或者通过像这样的类型转换来访问该方法
((Dog) b).bark();
超类引用变量可以保存子类对象,但使用该变量只能访问超类的成员,因此要访问两者的成员 类 建议始终创建引用变量以子类。
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()因为上面的语句说它可以访问只有超类的成员而不是 subclass.Following 这个逻辑 b.move() 的输出应该是 "Animals can move" 而不是 "Dogs can walk and run"。但这不是 case.Can有人帮我解决这个问题吗?提前致谢!
恭喜 - 您刚刚发现了多态性。
在Java中,类是动态绑定的。也就是说,如果您正在调用一个方法,则会调用对象的实现(在您的情况下为 Dog
),而不是引用类型的方法(在您的情况下为 Animal
)。
这允许覆盖方法并替换或完成它们的实现。
另一方面,您只能访问在您引用的类型中可用的方法,而不能访问实现类型(在您的情况下为 Animal
)。要调用实例的方法,您必须将其用作引用类型(在您的情况下为 Dog
)。
这段代码是错误的,因为行 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();
}
}
这将无法编译,因为 Animal
没有名为 bark
的方法。
这样想,所有的狗都是动物,但是并非所有的动物都是狗。所有的狗都会叫,但不是所有的动物都会叫。
在您的问题中,Animal
是父 class,它没有 bark()
方法,因此不会覆盖该方法。如果您能够在不声明或定义抽象方法的情况下从父 class 访问 bark()
,那么这将违反 Polymorphism 原则。
如果你真的想以这种方式访问它,那么你可以在你的父级中定义一个 abstract public void bark();
或者通过像这样的类型转换来访问该方法
((Dog) b).bark();