Java – 参考变量
“重要的是要理解它是引用变量的类型 – 而不是它引用的对象的类型 – 它决定了可以访问的成员。”
这句话你究竟是什么意思? 这仅限于inheritance的概念吗? JVM如何处理它?
这意味着假设你有:
Object x = "hello";
变量的类型是Object
,但它引用的对象的类型是String
。 它是变量类型,它决定了你可以做什么 – 所以你不能打电话
// Invalid String y = x.toUpperCase();
编译器只知道你在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)
例如:
Bike b = new Bike(); Bike b2 = new MountainBke(); b.speedUp(); b2.speedUp(); b2.shiftGearUp();
在上面的例子中,假设一辆自行车没有shiftUp
方法。 b2.shiftGearUp()
行无法编译,因为JVM只知道b2
是Bike
,而不是MountainBike
。
您可以通过将其投射到山地自行车类型来使其工作:
((MountainBike)b2).shiftGearUp(); // This compiles and runs propperly
在Java中, base
类类型的引用可以引用child
类的对象。 但是使用这样的引用,我们只能访问inheritance到child
类的base
类成员,而不能访问child
类可能添加的成员。
如果你有一个带有公共字段foo
的类Bar extends Foo
和一个类使用公共字段bar
Bar extends Foo
…
-
Foo myRef = new Bar();
只允许你访问myRef.foo
即使该对象真的是一个Bar
。 -
Bar myRef = new Bar();
允许访问myRef.foo
和myRef.bar
。 因为引用被声明为Bar
。
“重要的是要理解它是引用变量的类型 – 而不是它引用的对象的类型 – 它决定了可以访问的成员。”
这意味着编译器会检查引用变量的类是否存在方法和其他成员,例如,假设您有一个Dog
子类,它扩展了Animal
baseclass,
Animal obj=new Dog(); obj.makeSound();
这里编译器检查是否在Animal类中声明了makeSound()方法,以便编译它。
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 ChildMethod(); 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. } }