Java - 引用变量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2500555/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java - Reference Variables
提问by sgokhales
" It is important to understand that it is the type of reference variable - not the type of object that it refers to - that determines what members can be accessed. "
“ 重要的是要理解,是引用变量的类型——而不是它所引用的对象类型——决定了哪些成员可以被访问。”
What do you exactly mean by that statement ? Is this restricted to concept of Inheritance ? How does JVM handles it ?
你说的那句话到底是什么意思?这是否仅限于继承的概念?JVM 如何处理它?
采纳答案by Jon Skeet
It means that suppose you have:
这意味着假设你有:
Object x = "hello";
The type of the variableis Object, but the type of the object it refers to is String. it's the variable type which determines what you can do though - so you can't call
的类型的变量是Object,但对象的类型是指是String。变量类型决定了你可以做什么 - 所以你不能打电话
// Invalid
String y = x.toUpperCase();
The compiler only knows that you're calling a method on Object, which doesn't include toUpperCase. Similarly, overloaded methods are only resolved against the ones you know about:
编译器只知道你正在调用一个方法Object,它不包括toUpperCase. 同样,重载方法仅针对您所知道的方法进行解析:
public class Superclass
{
public void foo(Object x) {}
}
public class Subclass extends Superclass
{
public void foo(String y) {}
}
...
Subclass x = new Subclass();
Superclass y = x;
x.foo("hello"); // Calls Subclass.foo(String)
y.foo("hello"); // Calls Superclass.foo(Object)
回答by Chris Cudmore
public class Base
{
public object BaseMethod()
{
return new String("From Base");
}
}
public class Child extends Base
{
public object BaseMethod()
{
return new String("From Child.BaseMethod (overridden)");
}
public object ChildMethod()
{
return new String("From Child.ChildMethod");
}
}
public class Test
{
public static void main(String[] args)
{
Base base = new Child();
System.out.println(base.BaseMethod()); //prints "From Child.BaseMethod (overridden)"
System.out.println(base.ChildMethod()); //Will not compile as ChildMethod as reference is of type Base, and ChildMethod is not specified.
Child child = (Child) base; //But I can cast it.
System.out.println(child.ChildMethod()); // This will work.
}
}
回答by codaddict
In Java a reference of baseclass type can refer to a object of childclass. But using such a reference we can only access the members of the baseclass that were inherited to the childclass and not the members that the childclass might have added.
在 Java 中,base类类型的引用可以引用类的对象child。但是使用这样的引用,我们只能访问base继承到child该类的类成员,而不能访问child该类可能已添加的成员。
回答by Xr.
If you have a class Foowith a public field fooand a class Bar extends Foowith a public field bar...
如果您有一个Foo带有公共字段foo的类和一个Bar extends Foo带有公共字段的类bar......
Foo myRef = new Bar();will only allow you to accessmyRef.fooeven though the object is really aBar.Bar myRef = new Bar();allows access to bothmyRef.fooandmyRef.bar. Because the reference is declared asBar.
Foo myRef = new Bar();将只允许您访问myRef.foo即使对象是真的Bar。Bar myRef = new Bar();允许访问myRef.foo和myRef.bar。因为引用被声明为Bar.
回答by jjnguy
For example:
例如:
Bike b = new Bike();
Bike b2 = new MountainBke();
b.speedUp();
b2.speedUp();
b2.shiftGearUp();
In the above example, assume that a bike does not have the shiftUpmethod. The line b2.shiftGearUp()would not compile because the JVM only knows that b2is a Bike, not a MountainBike.
在上面的例子中,假设一辆自行车没有这个shiftUp方法。该行b2.shiftGearUp()不会编译,因为 JVM 只知道那b2是 a Bike,而不是MountainBike。
You could make it work by casting it to a mountain bike type:
您可以通过将其转换为山地自行车类型来使其工作:
((MountainBike)b2).shiftGearUp(); // This compiles and runs propperly
回答by Zaki
"It is important to understand that it is the type of reference variable - not the type of object that it refers to - that determines what members can be accessed. "
“重要的是要理解,是引用变量的类型——而不是它所引用的对象类型——决定了哪些成员可以被访问。”
What this means is that the compiler checks the class of the reference variable for the presence of methods and other members, for example, say that you have a Dogsubclass which extends Animalbaseclass,
这意味着编译器会检查引用变量的类是否存在方法和其他成员,例如,假设您有一个Dog扩展Animal基类的子类,
Animal obj=new Dog();
obj.makeSound();
Here the compiler checks whether the makeSound() method is declared in the Animal class or not for it to compile.
在这里,编译器检查是否在 Animal 类中声明了 makeSound() 方法以供编译。

