Dog dogObj = new Dog();
是的我知道我们必须为引用变量提供合适的类型,以便它可以为对象的位置地址或我们放入的地址保留一个位置。
引用变量存储位于寄存器堆中的真实对象的8字节地址(数字)。所以它的工作就是保存该位置的地址。为什么它需要一种类型呢?给它一个类型后,这个8字节有什么变化。它仍然可以指向该位置的8字节数据,即使它没有类型。
这背后的细节是什么?
答案 0 :(得分:3)
如果您想要一个可以保存任何参考值的变量,那么这很容易做到:
Object dogObj = new Dog();
但是,如果您尝试致电:
dogObj.bark();
...编译器不知道你在说什么,你不应该感到惊讶。编译器使用声明的变量类型来了解它的使用方式......就这么简单。
答案 1 :(得分:1)
阅读本文:http://www.javaranch.com/campfire/StoryCups.jsp
然后阅读其后续行动:http://www.javaranch.com/campfire/StoryPassBy.jsp
但基本上,你需要给它一个类型,以便编译器知道它的类型。请注意,您也可以这样做,这基本上就是您所说的:
Object dogObj = new Dog();
但是你只能在该变量上使用Object中定义的方法,因为编译器无法保证某些Object是否是更具体的类型。
编辑:我们假设你有两个班,狗和猫。 Dog有一个bark()方法,而Cat有一个meow()方法。
你可以这样做,因为正如你所说,引用是一个参考:
Object dog = new Dog();
但是,你不能做到这一点:
dog.bark();
尽管Dog类有一个bark()方法,而dog变量是Dog的一个实例,编译器并不知道。事实上,编译器不能知道什么。毕竟,你也可以这样做:
Object dog = new Dog();
dog = new Cat();
dog.bark(); //good thing this is a compiler error!
您可能会想,为什么编译器无法解决这个问题?原因是这样的代码可能发生:
Object dog = new Dog();
if(Math.random() < .5){
dog = new Cat();
}
//what type is dog now??
因此编译器只能保证Object是变量的类型。这就是为什么你需要给每个变量一个类型。
请注意,您还可以转换变量以明确告诉编译器类型是什么类型:
Object dog = new Dog();
dog = new Cat();
((Cat)dog).meow(); //this will now work, since the compiler knows dog is a Cat!
但请注意,因为如果您错了,您将收到运行时错误:
Object dog = new Dog();
dog = new Cat();
((Dog)dog).bark(); //this won't work, since dog is actually a Cat!
我强烈建议将您自己的小测试程序放在一起,运行类似于这些示例的代码,这样您就可以更好地了解正在发生的事情。
答案 2 :(得分:0)
声明不仅仅是内存分配。不使用类型的OOP不是OOP,您不是在操作原始字节,而是具有精确角色和精确逻辑的对象。这就是课程的用途。