【问题标题】:Access local variables in superclass constructor在超类构造函数中访问局部变量
【发布时间】:2015-03-18 19:42:43
【问题描述】:

我有一个具有这个构造函数的超类:

public Super(String p){
    String[] result = p.split(",");
    setA(result[0]);
    setB(result[1]);
    setC(result[2]);
    setD(result[3]);
    setE(result[4]);
}

然后我有一个子类,我想在其中使用相同的构造函数,但还要添加 2 个字符串。这是我的代码:

public Sub(String d){
    super(d);
    setF(result[5]);
    setG(result[6]);
}

使用此代码时,我收到未指定结果的错误。我该如何解决这个问题?

【问题讨论】:

  • 将其作用于类而不是构造函数。
  • 在超类还是在子类?
  • @tnw:根据我对 Andremoniy 的 cmets,如果这不是构造后实例的逻辑状态,你为什么要让它成为一个字段?这是一种非常讨厌的设计气味。
  • 在构造函数中调用方法通常也是代码异味。这对于返回 SuperSub 的工厂方法来说可能是一个不错的选择,并将各个参数传递给构造函数。
  • @JonSkeet 是的,这只是基于给出的信息的猜测。我不反对,但显然这是 OP 基于下面接受的答案所需要的。不过我更喜欢你的。

标签: java inheritance constructor constructor-chaining


【解决方案1】:

基本上,您需要在子类构造函数中再次进行拆分 - 局部变量 result 在子类构造函数中不可用:

public Sub(String d){
    super(d);
    String[] result = d.split(",");
    setF(result[5]);
    setG(result[6]);
}

是的,这最终会导致重复工作,但这有点难以避免。你可以通过一个私有子类构造函数来做到这一点,它接受一个String[],以及一个工厂方法来首先进行拆分:

protected Super(String[] result) {
    setA(result[0]);
    setB(result[1]);
    setC(result[2]);
    setD(result[3]);
    setE(result[4]);
}

protected Super(String d) {
    this(d.split(","));
}

...
private Sub(String[] result) {
    super(result);
    setF(result[5]);
    setG(result[6]); 
}

public static Sub fromString(String d) {
    return new Sub(d.split(","));
}

还有一个替代选项,超类构造函数调用一个在子类中被覆盖的虚方法,但这真的很脆弱,而且非常可怕,我什至不打算提供示例。

【讨论】:

  • 不是很高效的想法,会被拆分两次
  • @Andremoniy:我宁愿这样做,也不愿在课堂上有无关的状态。我现在包含了另一种方法。
  • 嗯,你想说,创建额外的方法——和静态类——比对象中的一个状态更好?
  • @Andremoniy:当然。不过,不确定“和静态类”是什么意思。我创建了替代构造函数和静态方法。每个对象的成本几乎为零......而您在创建的每个对象中引入了额外的空间,没有充分的理由。任何时候你有一个在构造函数中使用的字段,这就是一种令人讨厌的设计气味。不过,除非我发现这是一个问题,否则我可能只会花一点时间拆分两次。
  • “and static Class”是我的错,算了
猜你喜欢
  • 2017-05-18
  • 1970-01-01
  • 1970-01-01
  • 2023-03-12
  • 2011-09-05
  • 1970-01-01
  • 1970-01-01
  • 2018-06-16
  • 1970-01-01
相关资源
最近更新 更多