- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
在 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 个子类,添加这样一个带有参数的无意义传递构造函数到每个子类似乎是个坏主意!
对于大型类层次结构,有没有办法避免这个问题?
我知道一个参数的解决方案(有一个 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/
问题比较Java,但是我想在Android中实现: 假设有 3 个或更多类相互扩展: class A { ... int color; ... } class B extend
我知道标题听起来有点奇怪,但这正是我愿意做的。简单解释:A类是B类的子类,B类也是C类的子类>. 现在,所有这些类都包含方法m()。在我的 A 类中,这是我唯一可以访问的类,因为其他类仅在运行时可用,
我有一个 UIViewController 类 A 和 B。 A 使用以下方式加载 B:[A.view addSubView B.view]。 B 有一个带有“后退”按钮的导航栏。我想在单击时返回到
我有以下(第三方)类结构。我们将调用第三方项目 ProjectSeriously,并注意我使用 System.out.println 代替其他复杂的功能(100 行代码) . class A {
在下面的代码中,我从 Game 扩展了 MyGame。我有两个问题: 我们是否需要为所有render()、dispose()、pause()调用super方法 和 resize(w,h)?很多人都没有
例如,假设我想在调用 super.viewDidLoad() 时跳过一级。所以我希望能够做这样的事情: override func viewDidLoad() { super.super.vi
public class Faculty extends Employee { public static void main(String[] args) { new Fac
假设我有: class Superclass { //fields... methodA() {...} methodB() {...} ... } class Subclass exte
这个问题在这里已经有了答案: Why is super.super.method(); not allowed in Java? (22 个答案) 关闭 9 年前。 我怀疑我想做的事情是否可行。我有
我有一个实现 Initializable 的类。 public abstract class ExampleClass implements Initializable { public vo
我想知道,我有这个大数组,是否可以只在内存中使用一次而不是每个线程一次?以 stackoverflow 上的标签为例。他们几乎从不改变,为什么不为他们留下一个内存点呢?甚至可能将该数组永久保存在内存中
假设这三个类具有这个简单的层次结构: class A { func foo() { print("A") } } class B: A { override fu
有没有办法在 TypeScript 中调用 super.super.methodName。我想避免调用super.methodName,但我想调用二祖的methodName方法。 谢谢。 最佳答案 T
这个问题已经有答案了: When do I use super()? (11 个回答) 已关闭 7 年前。 package Geometry; public abstract class Geomet
我必须执行and()在我的实现 Predicate 的业务对象上. 出现问题的代码是 and() 行调用: Predicate predicate = new M
我有一个实现接口(interface)的抽象父类(super class): public abstract class FooMatrix implements Matrix { publi
我有四个 UIView:viewA 是 Root View ,它有 viewB 作为它的 subview 。 viewB 将 viewC 作为其 subview ,而 viewC 将 viewD 作为
有什么区别: class Child(SomeBaseClass): def __init__(self): super(Child, self).__init__() 和:
我有一个通用接口(interface) interface ListList extends List> .由于某些原因,我无法转换 ListList至 List> .有什么方法可以做到吗?为什么它不
我想调用带有两个参数的父类(super class)的构造函数,所以我调用了 super(arguments),但是编译器说: “类 Person 中的构造函数 Person 不能应用于给定类型; 要
我是一名优秀的程序员,十分优秀!