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 base
class type can refer to a object of child
class. But using such a reference we can only access the members of the base
class that were inherited to the child
class and not the members that the child
class might have added.
在 Java 中,base
类类型的引用可以引用类的对象child
。但是使用这样的引用,我们只能访问base
继承到child
该类的类成员,而不能访问child
该类可能已添加的成员。
回答by Xr.
If you have a class Foo
with a public field foo
and a class Bar extends Foo
with a public field bar
...
如果您有一个Foo
带有公共字段foo
的类和一个Bar extends Foo
带有公共字段的类bar
......
Foo myRef = new Bar();
will only allow you to accessmyRef.foo
even though the object is really aBar
.Bar myRef = new Bar();
allows access to bothmyRef.foo
andmyRef.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 shiftUp
method. The line b2.shiftGearUp()
would not compile because the JVM only knows that b2
is 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 Dog
subclass which extends Animal
baseclass,
这意味着编译器会检查引用变量的类是否存在方法和其他成员,例如,假设您有一个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() 方法以供编译。