Java 重载和覆盖的方法选择
Java method selection with overloading and overriding
我很难理解有关覆盖和重载的一些原则。
public class Figure{
public void stampa(Figure f){
System.out.println("Figure");
}
}
public class Square extends Figure{
public void stampa(Square q){
System.out.println("Square");
}
}
public class Rectangle extends Square{
public void stampa(Rectangle r){
System.out.println("Rectangle");
}
public void stampa(Square r){
System.out.println("Particular Rectangle");
}
public void stampa(Figure f){
System.out.println("Particular Figure");
}
}
public class Test{
public static void main(String args[]){
Figure f1,f2;
Square q = new Rectangle();
Rectangle r = new Rectangle();
f1 = new Square();
f2 = new Rectangle();
f1.stampa(f2); //Figure
q.stampa(r); //Particular Rectangle
f1.stampa(q); //Figure
q.stampa(f1); //Particular Figure
q.stampa(q); //Particupar Rectangle
}
}
我知道 public void stampa(Square q)
正在超载 public void stampa(Figure f)
而不是过度。
并且public void stampa(Rectangle r)
和public void stampa(Figure f)
也在重载public void stampa(Square q)
。
此外,矩形 class 中的 public void stampa(Square q)
覆盖了方形 class 中的方法。
第一题
关于这个结果:q.stampa(f1); //Particular Figure
我知道在编译时 q
是一个 Square
,所以我将在 Square
class 中查看此方法 public void stampa(Square q)
。在 运行 时间 q
是 Rectangle
所以我认为结果可能是 "Particular Rectangle" 而不是 "Particular Figure"
不确定我做错了什么
第二题
如果此时 Rectangle
扩展 Figure
而不再扩展 Square
,我肯定会在 Square q = new Rectangle();
上出现编译错误 [=19] =](将有一个变量 Square q
或者我们没有任何名称为 q 的变量?) q.stampa(f1);
的结果是什么
谢谢,对不起我的英语,如果我在某些时候错了,请纠正我。
第一个问题:
q
声明的类型是 Square。 f1
的声明类型是 Figure。因此编译器在 class Square 及其 superclasses 中查找名为 stampa 的方法,如果存在接受 Figure(或 Figure 的 superclass)的方法。它在图中找到一个:public void stampa(Figure f)
。在编译时,重要的是变量的声明类型。
现在,在运行时,检查 q
引用的对象的实际运行时类型:它是一个矩形。因此,运行时会在 Rectangle 中寻找覆盖 Figure 方法的方法 public void stampa(Figure f)
,以及 Figure 之前的所有超classes。这就是允许多态性的原因。它在矩形中找到一个:
public void stampa(Figure f) {
System.out.println("Particular Figure");
}
第二个问题:
您确实会遇到编译错误,因此对变量 q 的类型进行推理没有意义:不会有这样的变量,因为代码无法编译,而 class 是因此不是由编译器生成的。
I know that at compile-time q
is an Square
so i will look at this method public void stampa(Square q)
in Square class.
您忘记了 Square
包含 两个 方法:stampa(Square q)
和 stampa(Figure f)
。后者继承自Figure
,在编译时被选为最唯一合适的重载。
and at run-time q
is Rectangle so i thought the result might be "Particular Rectangle" instead of "Particular Figure"
重载在编译时选择,并在运行时覆盖。如前所述,stampa(Figure f)
在编译时已被选中。一旦它被实际调用,运行时就会看到 q
是 Rectangle
的一个实例,并将调用委托给 Rectangle.stampa(Figure f)
.
关于第二个问题,我不太明白你在问什么。编译错误意味着代码无效并且没有任何反应。 q.stampa(f1)
永远不会被调用,也永远不会 return 结果。
我很难理解有关覆盖和重载的一些原则。
public class Figure{
public void stampa(Figure f){
System.out.println("Figure");
}
}
public class Square extends Figure{
public void stampa(Square q){
System.out.println("Square");
}
}
public class Rectangle extends Square{
public void stampa(Rectangle r){
System.out.println("Rectangle");
}
public void stampa(Square r){
System.out.println("Particular Rectangle");
}
public void stampa(Figure f){
System.out.println("Particular Figure");
}
}
public class Test{
public static void main(String args[]){
Figure f1,f2;
Square q = new Rectangle();
Rectangle r = new Rectangle();
f1 = new Square();
f2 = new Rectangle();
f1.stampa(f2); //Figure
q.stampa(r); //Particular Rectangle
f1.stampa(q); //Figure
q.stampa(f1); //Particular Figure
q.stampa(q); //Particupar Rectangle
}
}
我知道 public void stampa(Square q)
正在超载 public void stampa(Figure f)
而不是过度。
并且public void stampa(Rectangle r)
和public void stampa(Figure f)
也在重载public void stampa(Square q)
。
此外,矩形 class 中的 public void stampa(Square q)
覆盖了方形 class 中的方法。
第一题
关于这个结果:q.stampa(f1); //Particular Figure
我知道在编译时 q
是一个 Square
,所以我将在 Square
class 中查看此方法 public void stampa(Square q)
。在 运行 时间 q
是 Rectangle
所以我认为结果可能是 "Particular Rectangle" 而不是 "Particular Figure"
不确定我做错了什么
第二题
如果此时 Rectangle
扩展 Figure
而不再扩展 Square
,我肯定会在 Square q = new Rectangle();
上出现编译错误 [=19] =](将有一个变量 Square q
或者我们没有任何名称为 q 的变量?) q.stampa(f1);
谢谢,对不起我的英语,如果我在某些时候错了,请纠正我。
第一个问题:
q
声明的类型是 Square。 f1
的声明类型是 Figure。因此编译器在 class Square 及其 superclasses 中查找名为 stampa 的方法,如果存在接受 Figure(或 Figure 的 superclass)的方法。它在图中找到一个:public void stampa(Figure f)
。在编译时,重要的是变量的声明类型。
现在,在运行时,检查 q
引用的对象的实际运行时类型:它是一个矩形。因此,运行时会在 Rectangle 中寻找覆盖 Figure 方法的方法 public void stampa(Figure f)
,以及 Figure 之前的所有超classes。这就是允许多态性的原因。它在矩形中找到一个:
public void stampa(Figure f) {
System.out.println("Particular Figure");
}
第二个问题:
您确实会遇到编译错误,因此对变量 q 的类型进行推理没有意义:不会有这样的变量,因为代码无法编译,而 class 是因此不是由编译器生成的。
I know that at compile-time
q
is anSquare
so i will look at this methodpublic void stampa(Square q)
in Square class.
您忘记了 Square
包含 两个 方法:stampa(Square q)
和 stampa(Figure f)
。后者继承自Figure
,在编译时被选为最唯一合适的重载。
and at run-time
q
is Rectangle so i thought the result might be "Particular Rectangle" instead of "Particular Figure"
重载在编译时选择,并在运行时覆盖。如前所述,stampa(Figure f)
在编译时已被选中。一旦它被实际调用,运行时就会看到 q
是 Rectangle
的一个实例,并将调用委托给 Rectangle.stampa(Figure f)
.
关于第二个问题,我不太明白你在问什么。编译错误意味着代码无效并且没有任何反应。 q.stampa(f1)
永远不会被调用,也永远不会 return 结果。