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 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
.
"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.
}
}
精彩评论