开发者

Java - Reference Variables

" It is important to understand that it is the type of reference开发者_如何学Go 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 ?


It means that suppose you have:

Object x = "hello";

The type of the variable is 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

// 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:

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)


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.

You could make it work by casting it to a mountain bike type:

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


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.


If you have a class Foo with a public field foo and a class Bar extends Foo with a public field bar...

  • Foo myRef = new Bar(); will only allow you to access myRef.foo even though the object is really a Bar.
  • Bar myRef = new Bar(); allows access to both myRef.foo and myRef.bar. Because the reference is declared as Bar.


"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,

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.


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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜