“了解这一点非常重要 它是引用变量的类型 - 不是它引用的对象类型 - 确定成员可以做什么 被访问。 “
这句话你究竟是什么意思? 这仅限于继承的概念吗? JVM如何处理它?</ p>
答案 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只知道b2
是Bike
,而不是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.foo
和myRef.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()方法,以便编译它。