方法重写和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)
PlaneCircle
的toString()
方法调用super.toString()
,当我使用getClass().getSimpleName()
super.toString()
, Circle
的toString()
方法应该给出“Circle”。
我的问题是,为什么在这种情况下输出是“PlaneCircle”而不是“Circle”,即使我已经创建了子类的实例(PlaneCircle)? 这与reflection有什么关系吗?
planeCircle1
是planeCircle1
的一个实例,这意味着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的方法。