方法重写和inheritance

public class Circle { public static final double PI = 3.141592654; protected double radius; public Circle(double radius) { this.radius = radius; } @Override public String toString() { return "Class = " + getClass().getSimpleName() + " (radius = " + radius + ")"; } } public class PlaneCircle extends Circle { private double centerX, centerY; public PlaneCircle(double radius, double centerX, double centerY) { super(radius); this.centerX = centerX; this.centerY = centerY; } @Override public String toString() { return super.toString(); } } 

假设上面两个类在不同的文件中。

当我创建PlaneCircle的实例(在另一个java文件中),如下面两行…

 PlaneCircle planeCircle1 = new PlaneCircle(3, 6, 7); System.out.println(planeCircle1.toString()); 

我在控制台输出中得到的是

 Class = PlaneCircle (radius = 3.0) 

PlaneCircletoString()方法调用super.toString() ,当我使用getClass().getSimpleName() super.toString()CircletoString()方法应该给出“Circle”。

我的问题是,为什么在这种情况下输出是“PlaneCircle”而不是“Circle”,即使我已经创建了子类的实例(PlaneCircle)? 这与reflection有什么关系吗?

planeCircle1planeCircle1的一个实例,这意味着getClass()将返回PlaneCircle.class (即表示PlaneCircle类的Class实例)和getClass().getSimpleName()将返回该类的名称 – “PlaneCircle”。

从基类Circle的方法调用getClass().getSimpleName()并不重要,因为当你调用没有实例变量的方法时,你在当前实例上调用它(即getClass()是与this.getClass()相同, this是代码示例中PlaneCircle一个实例。

getClass()也是多态的 – 它返回一个Class对象,表示它所属的实例,在本例中是PlaneCircle 。 如果您不想要这种行为,您可以硬编码Circle

 @Override public String toString() { return "Class = circle (radius = " + radius + ")"; } 

或者静态访问Circle类:

 @Override public String toString() { return "Class = " + Circle.class.getSimpleName() + " (radius = " + radius + ")"; } 

由于您在PlaneCircle的实例而不是Circle ,因此将在您当前的PlaneCircle实例上调用getClass.getSimpleName() 。 使用当前设置,您可能无法使用多态行为打印“Circle”。 在运行时,将调用PlaneCircle的方法。