好吧,我创建了两个类parent和child,child扩展了parent,它们都有一个名为print的函数。 然而,子类有两个打印函数,一个是参数化的,另一个不是(在子类中重载打印函数)。
父类只有一个打印函数。
现在当我制作这样的物体时
父 p = new child();
它给出了编译错误,但它不应该出现,我不知道为什么?
代码片段:
class temp {
public static void main(String[] args) {
try {
parent p = new child();
p.print();
p.print(1);
}catch (Exception e){
System.out.println(e.getStackTrace());
}
}
}
class parent {
void print() {
System.out.println("parent print function");
}
}
class child extends parent {
void print() {
System.out.println("child print function");
}
void print(int i) {
System.out.println("child parameterized print function");
}
}
现在,由于子级继承了父级,因此它们的构造函数都将被调用,但最终创建的对象是子类对象,因此在运行 print(1) 时不应给出错误,因为子级具有 print(int i ) 函数,但是它给出一个错误,父类没有 print(int i) 函数。
现在,对于另一个场景,我也在父类中添加 print(int i) 函数,然后一切都按预期进行,父类的函数被子类覆盖。
此外,如果我只在父函数中添加一个 print(int i) 函数并将其从子函数中删除,那么此代码也可以工作并打印该父函数,这也是预期的行为。
这是唯一似乎给出错误的情况, 如果有人可以分享对此的一些见解,那将非常有帮助,谢谢:)。
parent p = new child();
p.print();
p.print(1); // <<--- This method is only in child, meaning you cannot call it on the parent variable without casting it to a child
这是因为您将变量
p
声明为 parent
: 类型
parent p = new child();
当然,您已经为 p
分配了 child
类型的值,但静态类型仍然是 parent
,并且编译器无法做出任何超出此范围的假设。假设您创建了 parent
的另一个子类,如下所示:
class StepChild extends parent {
void print(String i) {
System.out.println("step child parameterized print function");
}
}
然后您可以将
StepChild
类型的值分配给 p
:
p = new StepChild();
StepChild
没有采用 print
的 int
方法,因此在这种情况下调用 p.print(1)
将是一个错误。
如果您希望能够调用只属于特定类型的方法,则需要告诉编译器它至少是该类型。对于您的情况,您可以这样做:child p = new child();
。现在编译器知道 p 实际上是一个 child
,并且不能被分配一个没有 print(int)
方法的值,因此您可以安全地调用 print(1)
;
这类似于说,知道你有某种车辆,但你不知道它是自行车还是汽车。如果你尝试打开引擎,但你有一辆自行车,那将会失败。但是,您知道,无论您拥有哪种特定类型的车辆,您都可以使用它将自己从一个地点运送到另一个地点。有些语言会让你在不知道具体车辆类型的情况下尝试打开引擎,并让你在运行时失败。 Java 不允许您这样做(至少非常容易),并且只允许您调用它确定接收类型具有的方法。