Java 重写说明
这是我的代码
class Glyph {
void draw() { System.out.println("Glyph.draw()"); }
Glyph(int i) {
System.out.println("Glyph() before draw()");
draw();
System.out.println("Glyph() after draw()");
}
}
class RoundGlyph extends Glyph {
private int radius = 1;
RoundGlyph(int r) {
super(r);
radius = r;
System.out.println("RoundGlyph.RoundGlyph(), radius = " + radius);
}
void draw() {
System.out.println("RoundGlyph.draw(), radius = " + radius);
}
}
public class PolyConstructors {
public static void main(String[] args) {
new RoundGlyph(5);
}
}
输出:
Glyph() before draw()
RoundGlyph.draw(), radius = 0
Glyph() after draw()
RoundGlyph.RoundGlyph(), radius = 5
为什么超类Glyph
的构造函数调用子类RoundGlyph
的draw方法?如何从超类的构造函数中调用超类的draw方法?我尝试过这个但没有成功......
Here is my code
class Glyph {
void draw() { System.out.println("Glyph.draw()"); }
Glyph(int i) {
System.out.println("Glyph() before draw()");
draw();
System.out.println("Glyph() after draw()");
}
}
class RoundGlyph extends Glyph {
private int radius = 1;
RoundGlyph(int r) {
super(r);
radius = r;
System.out.println("RoundGlyph.RoundGlyph(), radius = " + radius);
}
void draw() {
System.out.println("RoundGlyph.draw(), radius = " + radius);
}
}
public class PolyConstructors {
public static void main(String[] args) {
new RoundGlyph(5);
}
}
Output:
Glyph() before draw()
RoundGlyph.draw(), radius = 0
Glyph() after draw()
RoundGlyph.RoundGlyph(), radius = 5
Why is the constructor of the superclass Glyph
calling the draw method of the subclass RoundGlyph
? How can I call the draw method of the superclass from the constructors of the superclass? I tried this but it didn't work....
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
这就是方法重写的工作方式。如果子类实现了与其父类(或祖父等)具有相同签名的方法,则当其祖先之一调用该方法而不指定
super.
时,将调用子类的版本。没有办法指定调用方法的我的版本,而不是子类的版本。
请注意,除了设置类所需的操作之外,您不应在构造函数中执行任何其他操作。
This is the way that method overriding works. If a subclass has implemented a method with the same signature as its parent (or grandparent, etc), when one of its ancestors calls that method without specifying
super.
, the sublcass's version will be called.There isn't a way to specify calling my version of a method, as opposed to a subclass's version.
Please note that you shouldn't do any work in a constructor other than what is necessary to set up the class.
从构造函数调用非私有或非静态方法是不好的做法,因为从构造函数调用非私有或非静态方法将导致调用子类型中的方法,就像您的情况一样。
因此,不要这样做并更改应用程序的设计。
It's bad practice to call non-private or non-static methods from ctors, because call to non-private or non-static method from ctor will result in calling method in subtype, just as in your case.
So, don't do this and change design of your application.
我同意关于这对建造者来说是糟糕的设计的答案。但是,如果您需要从基类内部调用基类方法,则需要将代码提取到未重写的方法中。实例化的子类对象将始终执行重写的方法。
I agree with the answers regarding this is bad design for constructors. But if you need to call a base-class method from inside the base-class, you need to extract the code into a not overridden method. A instantiated subclass object will always execute the overridden method.
你不能。在 Java 中,所有方法都是虚拟的,您无法指定要执行继承层次结构中的哪个方法。唯一的例外是子类可以调用其父类的方法,即使它们自己重写它。
如果您不希望某个方法被重写,请将其声明为final(或私有)。
You can't. All methods are virtual in Java and you cannot specify which in the inheritance hierarchy you want to execute. The only exception is that subclasses can call their parent's methods even if they themselves override it.
If you don't want a method to be overridable, declare it as final (or private).
基类构造函数正在调用子类
draw()
方法,因为您正在创建子类类型的对象。这就是它应该如何工作的。子类的方法由类加载器加载,而不是在调用构造函数时加载,因此它们已经可供构造函数执行。请参阅 JLS 的相关部分更多信息。您无法按照您尝试的方式从子类的实例调用基类
draw()
方法。您需要不重写子类中的方法,或者更改您的设计以封装Glyph
而不是扩展它。The base class constructor is calling the sub class
draw()
method because you're creating an object of the sub class type. This is how it's supposed to work. The methods for the sub class are loaded by the class loader, not when the constructor gets called, so they're already available to be executed by the constructor. See the relevant section of the JLS for more information.You can't call the base class
draw()
method from an instance of the subclass in the way you're attempting. You'd need to either not override the method in the subclass, or change your design to encapsulateGlyph
instead of extending it.