Java - 参考变量

时间:2010-03-23 14:13:01

标签: java

  

“了解这一点非常重要   它是引用变量的类型 -   不是它引用的对象类型    - 确定成员可以做什么   被访问。 “

这句话你究竟是什么意思? 这仅限于继承的概念吗? JVM如何处理它?<​​/ p>

6 个答案:

答案 0 :(得分:26)

这意味着假设你有:

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)

答案 1 :(得分:5)

例如:

Bike b = new Bike();
Bike b2 = new MountainBke();
b.speedUp();
b2.speedUp();
b2.shiftGearUp();

在上面的示例中,假设自行车没有shiftUp方法。行b2.shiftGearUp()无法编译,因为JVM只知道b2Bike,而不是MountainBike

你可以通过将其投射到山地自行车类型来使其工作:

((MountainBike)b2).shiftGearUp(); // This compiles and runs propperly

答案 2 :(得分:2)

在Java中,base类类型的引用可以引用child类的对象。但是使用这样的引用,我们只能访问继承到base类的child类的成员,而不能访问child类可能添加的成员。

答案 3 :(得分:1)

如果您的班级Foo包含公开字段foo,而班级Bar extends Foo包含公开字段bar ...

  • Foo myRef = new Bar();只允许您访问myRef.foo,即使该对象确实是Bar
  • Bar myRef = new Bar();允许访问myRef.foomyRef.bar。因为引用声明为Bar

答案 4 :(得分:0)

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.
   }
}

答案 5 :(得分:0)

  

“理解它很重要   是引用变量的类型 -   不是它引用的对象类型    - 确定成员可以做什么   被访问。 “

这意味着编译器会检查引用变量的类是否存在方法和其他成员,例如,假设您有一个Dog子类,它扩展了Animal baseclass,< / p>

Animal obj=new Dog();
obj.makeSound();

这里编译器检查是否在Animal类中声明了makeSound()方法,以便编译它。