gpt4 book ai didi

java - 我怎样才能避免在子类中创建无用的传递构造函数只是为了将参数传递给 "super()"?

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:21:18 25 4
gpt4 key购买 nike

在 Java 中,据我所知,子类不会继承具有参数的构造函数。

例如

public class Parent {
public Parent(int x) {
DoSomethingWithX(x);
}
}

public class Child extends Parent {
// Compile fails with "Implicit super constructor Parent() is undefined
// for default constructor. Must define an explicit constructor
}

修复它的唯一方法是在 Child 类中创建一个无用的传递构造函数:

public class Child extends Parent {
public Child(int x) {
super(x);
}
}

问题:

如果我有一个复杂的子类层次结构,有 6-10 个子类,添加这样一个带有参数的无意义传递构造函数到每个子类似乎是个坏主意!

  • 简单的代码看起来很愚蠢(10 个类中相同方法的 10 个副本)
  • 更糟糕的是,与任何代码重复一样,代码变得脆弱 - 需要在 10 个地方而不是一个地方进行任何更改(例如,再添加 1 个参数)。

问题:

对于大型类层次结构,有没有办法避免这个问题?

注意事项:

我知道一个参数的解决方案(有一个 setter,必须与构造函数分开调用)。但是这个解决方案有几个很大的缺点,因此不被接受。

最佳答案

大约 15 年前,我遇到了一个与您的问题类似的问题,它具有非常广泛(但只是稍微深一点)的层次结构(是的,伙计们,这是有原因的) .但是,由于它们都派生 self 们定期需要向其添加更多信息的基类,因此很快就会发现,向基类构造函数添加参数非常痛苦。

默认情况下不继承构造函数是件好事,但有时您希望继承它们。有时我想要一个可以添加到类中的编译时注释,以告诉编译器“为我没有明确实现的任何 super 构造函数自动生成构造函数”。但我们没有它,如果 JSR 完全成功,则需要数年时间才能完成......

没有那个神奇的注释,我们使用的解决方案正是@psabbate mentioned in his/her comment :

what if your constructors receive a Map, or a CustomClass class that contains every parameter you could possible need. That way if you need to change parameters and arguments you can only change the class you are interested about.

...但是参数类具有特定的类型层次结构(不是 Map)。

为了完整起见,举个例子:

// The standard parameters needed
class StandardParams {
private String thisArg;

public StandardParams(String thisArg) {
this.thisArg = thisArg;
}

public String getThisArg() {
return this.thisArg;
}
}

// The base class
class Base {
public Base(StandardParams args) {
System.out.println("Base: " + args.getThisArg());
}
}

// A standard subclass
class Sub1 extends Base {
public Sub1(StandardParams args) {
super(args);
System.out.println("Sub1 thisArg: " + args.getThisArg());
}
}

对我来说,这甚至不是“最不糟糕的”。具有表示层次结构所需的基本信息的类型是富有表现力的。

如果一个子类需要比标准参数更多的信息(这是为我们准备的),您可以选择第二个参数类类型作为第二个参数(但是树中有两种类型的构造函数) 或在参数类层次结构中使用继承;我们使用了后者:

// Extended parameters (naturally you make these names meaningful)
class ExtendedParams extends StandardParams {
private String thatArg;

public ExtendedParams(String thisArg, String thatArg) {
super(thisArg);
this.thatArg = thatArg;
}

public String getThatArg() {
return this.thatArg;
}
}

// A subclass requiring extended parameter information
class Sub2 extends Base {
public Sub2(ExtendedParams args) {
super(args);
System.out.println("Sub2 thisArg: " + args.getThisArg());
System.out.println("Sub2 thatArg: " + args.getThatArg());
}
}

在我的案例 IIRC 中,我们只有三个参数类(树中特定分支的标准一个和两个子类)跨越层次结构中大约 30 个主要类。

最后一点:对我们来说,在构建参数类时,我们需要向参数类提供一组核心内容,这些内容没有变化,并且有大约八个选项具有合理的基本默认值,但您可以覆盖.为了避免参数类中构造函数的爆炸式增长,我们最终对它们做了一些穷人的构建器模式(“穷人的”因为我们让这些类成为它们自己的构建器而不是将它们分开;这只是没有必要为了 对其严格,更改的内容具有廉价的默认值,因此即使在构建时实例也始终处于有效状态)。所以我们的构造看起来像这样:

Thingy t = new Thingy(
new ThingyParams(basic, construction, info)
.withAnswer(42)
.withQuestion("Life, the Universe, and Everything")
);

关于java - 我怎样才能避免在子类中创建无用的传递构造函数只是为了将参数传递给 "super()"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39732984/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com