我觉得我对Java中的继承有一个很好的理解,但我正在努力解决以下问题:
public class SuperClass {
private String name;
private int age;
public SuperClass(String name, int age) {
this.name = name;
this.age = age;
}
public void sharedMethod() {
System.out.println("I'm a shared method in the SuperClass");
}
}
public class SubClass extends SuperClass {
public SubClass(String name, int age) {
super(name, age);
}
public void sharedMethod() {
System.out.println("I'm a shared method in the SubClass");
}
public void subMethod() {
System.out.println("I'm subMethod");
}
}
public class Main {
public static void main(String args[]) {
SuperClass test = new SubClass("Laura", 30);
test.sharedMethod();
test.subMethod(); // causes an error
}
}
在使用SuperClass test = new SubClass("Laura", 30);
时,我主要是在努力了解这里实际创建的内容(只有在SubClass
扩展SuperClass
时似乎才有效 - 如果没有强制转换,该怎么办? ?)。
我不理解它的原因是因为我可以调用sharedMethod
来打印SubClass
方法中的文字(因此大概SubClass
会覆盖SuperClass
1}}此方法中的方法),但我无法从subMethod
调用SubClass
。对不起,如果我没有表达清楚,我似乎无法理解所引用的内容,可以使用的方法,为什么要这样做,为什么SubClass
如果方法是共享的,则覆盖方法,但不能以其他方式调用。
答案 0 :(得分:2)
按SuperClass test = new SubClass("Laura", 30)
,您可以创建SubClass
个实例,但可以SuperClass
引用它。
在编译阶段,编译器发现SuperClass
没有方法subMethod
,因此会出现编译错误。
在运行时,JVM发现test
实际上是SubClass
,因此来自sharedMethod
的{{1}}:
SubClass
将被执行。
答案 1 :(得分:1)
让我们说你告诉别人你有一辆车:
class Vehicle {
public void drive() {
System.out.println("Driving vehicle");
}
}
这意味着,你告诉的人知道你有能力驾驶......但是,你有一辆摩托车:
class Motorcycle extends Vehicle {
public void wheely() {
System.out.println("Doing a wheely");
}
public void drive() {
System.out.println("Driving motorcycle");
}
}
哪个可以drive()
,因为它是Vehicle
,也可以wheely()
。但是,你从未告诉过他们你所拥有的汽车类型是摩托车。因此,他们知道你能做的最多就是开车。
此人拥有的知识水平与对象参考类似:
Vehicle vehicle = new Motorcycle();
Vehicle
引用仅知道您是Vehicle
。它并不重要"如何"你开车,它只知道你知道怎么开车。因此,当您致电drive()
时,它会驱动Motorcycle
驾驶(被覆盖的方法)的方式,但您仍在驾驶。
但是,如果你更具特异性并告诉别人你拥有的车辆类型是摩托车,那么你就会向他们提供有关你车辆功能的更多信息。
Motorcycle motorcycle = new Motorcycle();
你知道,因为它是Vehicle
,它仍然可以完成车辆可以做的所有事情drive()
。但是,既然您现在已经引用了子类,那么您可以更多地了解它可以做什么 - wheely()
。
编译器不能进行假设,因此如果你创建一个LESS特定的引用Vehicle v
(一个超类),编译器将只访问它知道它有权访问的那个对象的元素。如果你做了一个更具体的引用(一个子类),那么你告诉编译器更多关于该对象可以做什么。