Java 在super()之前调用子属性?
我主要使用动态语言——我刚刚开始使用Java,正在与静态模式作斗争 据我所知,子类构造函数中的第一个调用必须是对其父类的调用。这很好,但我需要在子对象中设置实例变量,这些变量在父对象的构造函数中引用……当然,这会创建一个catch-22。(在调用父级之前需要在子级中设置变量,但在子级中设置变量之前需要调用父级) 我肯定我打破了某种静态语言模式或规律……我只是不确定是哪一种,或者如何重新设计它。谢谢你的帮助。下面是一个简单的例子:Java 在super()之前调用子属性?,java,Java,我主要使用动态语言——我刚刚开始使用Java,正在与静态模式作斗争 据我所知,子类构造函数中的第一个调用必须是对其父类的调用。这很好,但我需要在子对象中设置实例变量,这些变量在父对象的构造函数中引用……当然,这会创建一个catch-22。(在调用父级之前需要在子级中设置变量,但在子级中设置变量之前需要调用父级) 我肯定我打破了某种静态语言模式或规律……我只是不确定是哪一种,或者如何重新设计它。谢谢你的帮助。下面是一个简单的例子: Class Race { public Race(Venue
Class Race {
public Race(Venue event_venue) {
greeting();
}
public void greeting() {
String event_greeting = String.format("The next event is: %s", getName());
System.out.println(event_greeting);
}
public String getName() {
return getClass().getSimpleName();
}
}
Class Sprint extends Race {
private int event_distance;
public Sprint(Venue event_venue, int distance) {
// super has to be the first call
super(event_venue);
// but I need to set event_distance to reference getName() in parent constructor
setDistance(distance);
}
public String getName() {
String sprint_name = String.format("%s meter sprint", Integer.toString(getDistance());
return sprint_name;
}
public int getDistance() {
return distance;
}
public void setDistance(int distance) {
event_distance = distance;
}
}
你的构造器有副作用,这是不受欢迎的。为了获得最佳效果,将副作用放在另一种方法中。您已经有了这一点,所以只需在javadoc中指定在构造之后应该调用
greeting()
(或者,它可以由子类构造函数调用,但是子类也会有同样的问题)。我假设每个种族都有一个距离,那么为什么不将此字段作为超类型的一部分呢。然后可以通过提供给构造函数的参数设置此字段
Class Race {
private int event_distance;
public Race(Venue event_venue, int distance) {
this.distance = distance;
greeting();
}
public void greeting() {
String event_greeting = String.format("The next event is: %s", getName());
System.out.println(event_greeting);
}
public String getName() {
return getClass().getSimpleName();
}
public int getDistance() {
return distance;
}
public void setDistance(int distance) {
event_distance = distance;
}
}
将距离作为参数提供给超级构造函数:
Class Sprint extends Race {
private int event_distance;
public Child(Venue event_venue, int distance) {
super(event_venue, distance);
}
/* omitted rest of class */
}
是的,那不行 您需要重构代码,使其能够以正确的顺序执行构造函数。通常,如果构造函数没有副作用,并且不调用可以在子类中重写的方法(两者都是不推荐的模式),那么这就不是问题
这很好,但我需要在子对象中设置实例变量,这些变量在父对象的构造函数中引用。您的父对象不应该知道子对象。您的意思是希望在创建新的Sprint对象时调用
Sprint 35; getName()
,我理解正确吗?@TheNewIdiot,这是否意味着老年退休金计划的问题无法解决?如果不是“了解未来”儿童,那么抽象的方法是什么?如果你是对的,那是一个糟糕的设计。父类应该是抽象的。
public Race(Venue event_venue) {
greeting(); // constructor should not call non-final method
}
// method called by a constructor should not print anything
public void greeting() {
String event_greeting = String.format("The next event is: %s", getName());
System.out.println(event_greeting);
}