我感到困惑:我从一个学习资源中摘取了下面这些引用(带有它们所在章节的标题),但是这些引用似乎互相矛盾。
超类引用和子类对象
"决定可以访问哪些成员的是引用变量的类型,而不是它所引用的对象的类型"
覆盖方法支持多态
"确定执行哪个覆盖方法的版本的是被引用对象的类型,而不是引用变量的类型"
如果能对此进行澄清,将不胜感激。
"决定可以访问哪些成员的是引用变量的类型,而不是它所引用的对象的类型"
"确定执行哪个覆盖方法的版本的是被引用对象的类型,而不是引用变量的类型"
如果能对此进行澄清,将不胜感激。
class Vehicle{
public void drive(){
System.out.println("Vehicle is Moving");
}
}
class Car extends Vehicle{
public void drive(){
System.out.println("Car is Moving");
}
public void playMusic(){
System.out.println("Car is Playing Music");
}
}
“决定可以访问哪些成员的是引用变量的类型,而不是它所引用的对象的类型。”
这意味着如果我们有如下代码:
Vehicle vehicle = new Car();
使用 vehicle
对象,我们可以调用 drive()
方法,但不能调用 playMusic()
方法,因为 vehicle
的类型是 Vehicle
。
“执行哪个被覆盖方法的版本取决于被引用对象的类型(而不是引用变量的类型)。”
这意味着如果我们有如下代码:
Vehicle vehicle = new Car();
vehicle.drive();
它将打印“Car is Moving”而不是“Vehicle is Moving”,因为存储在vehicle
中的对象是Car
类的实例。
class SuperMem{
int i = 90;
int j = 100;
void show(){
System.out.println("parent show..");
System.out.println("Show inside Parent start");
System.out.println(i + " " + j);
System.out.println("Show inside Parent END");
}
}
class submem extends SuperMem{
int i = 10;
int j = 20;
void show(){
System.out.println("Child show ..");
System.out.println("Show inside Child start");
System.out.println(i + " " + j);
System.out.println("Show inside Child END");
}
}
public class SuperMemDemo {
public static void main(String[] args) {
SuperMem m = new SuperMem();
submem s = new submem();
m = s;
System.out.println("i " + m.i);
System.out.println("j " + m.j);
m.show();
}
}
输出:
i 90
j 100
Child show ..
Show inside Child start
10 20
Show inside Child END
ClassA a = new ClassB ();
使用变量a
,您只能访问在ClassA
中定义的成员(或者是ClassA
的超类或实现ClassA
接口的接口)。您无法访问在ClassB
中定义但未在ClassA
中定义的成员(除非将a
强制转换为ClassB
)。
然而,调用在ClassB
中覆盖的ClassA
方法将执行ClassB
方法。
超类引用和子类对象
假设Child继承自Parent,让我们看一下这个例子:
Parent obj = new Child();
obj
,我们只能使用父类中指定的行为(方法)。我们无法使用来自子类的任何新方法。public String whoAmI()
。 return "Parent";
子元素:
return "Child";
现在如果我们运行这段代码:
Parent obj1 = new Child();
Parent obj2 = new Parent();
System.out.println(obj1.whoAmI());
System.out.println(obj2.whoAmI());
输出:
Child
Parent
因此,您只能通过引用它的类(第一个片段中的Parent)访问该类中的方法。但是,如果您已在实例化为的类(第一个片段中的Child)中覆盖了它,并在子类中重写了父类中的方法,则调用父类中存在的方法将调用在子类中重写的方法。