我目前正在阅读一本Java书籍,并且已经开始阅读有关继承和多态性的内容。
我正在编写一个存储动物信息的测试程序,并且我想重载设置动物大小的方法。用户知道狗的大小,但不知道其他动物的大小,因此如果它不是狗,则将动物大小设置为0,对于狗,它使用自己的带参数的setSize方法。
然而,我尝试了两种创建狗的方法,通过创建动物对象和通过创建狗对象。我假设即使testDog1变量的类型是Animal,它仍然能够重载来自Dog类的方法,因为它是一个狗对象。
有人能解释一下为什么testDog1不能工作而testDog2能工作吗?
public class Loader {
public static void main(String[] args){
int dogSize = 100;
Animal testDog1 = new Dog();
testDog1.setSize(dogSize);
Dog testDog2 = new Dog();
testDog2.setSize(dogSize);
}
}
public class Animal {
public int size;
public void setSize(){
size = 0;
System.out.println(size);
}
}
public class Dog extends Animal {
public void setSize(int dogSize){
size = dogSize;
System.out.println(size);
}
}发布于 2015-08-18 19:31:26
如果您打算在代码中引用testDog1,编译器会认为它属于Animal类。这意味着您可以将其重新分配给Cat或Bird的实例或其他任何不存在setSize(int)的地方。
在testDog1被声明为Animal类型的之后,您需要遵守该类的约定。
it 是,当前是一个Dog,这一事实并不能使Dog的具体方法可见。不过,你可能会在本书的下一章中了解到有关选角的知识。
发布于 2015-08-18 20:03:17
Animal testDog1 = new Dog();只有在运行程序时,才会创建Dog的实例并将其分配给testDog1变量。即)运行时。
编译器在检查correctness.Had时不会运行程序,也不会硬性地假设每个语句或变量的性质,下面的stmt也会成为编译时错误。
Animal testDog = null;
testDog.setSize(); // How can you call setSize() on null right? for the same reason mentioned above.发布于 2015-08-18 19:31:28
在编译时,编译器所知道的就是在testDog1中会有一个对Animal的引用。由于Animal没有setSize(int),因此编译器无法定位它,因此会失败。
重要的是要知道哪些操作是在编译时完成的(编译器知道变量的类型),哪些操作是在运行时完成的(运行时知道对象的实际实例)。
https://stackoverflow.com/questions/32071123
复制相似问题