在 Scala 中,如何使用多个构造函数子类化 Java 类?
假设我有一个具有多个构造函数的 Java 类:
class Base {
Base(int arg1) {...};
Base(String arg2) {...};
Base(double arg3) {...};
}
如何在 Scala 中扩展它并仍然提供对 Base 的所有三个构造函数的访问?在 Scala 中,子类只能调用其超类的构造函数之一。我该如何解决这个规则?
假设 Java 类是我无法更改的遗留代码。
Suppose I have a Java class with multiple constructors:
class Base {
Base(int arg1) {...};
Base(String arg2) {...};
Base(double arg3) {...};
}
How can I extend it in Scala and still provide access to all three of Base's constructors? In Scala, a subclass can only call one of it's superclass's constructors. How can I work around this rule?
Assume the Java class is legacy code that I can't change.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
人们很容易忘记特征可以扩展类。如果您使用特征,则可以推迟决定调用哪个构造函数,如下所示:
Scala 2 特征本身可能没有构造函数参数,但您可以通过使用抽象成员来解决这个问题。
(Scala 3 允许特征具有构造函数参数。)
It's easy to forget that a trait may extend a class. If you use a trait, you can postpone the decision of which constructor to call, like this:
Scala 2 traits may not themselves have constructor parameters, but you can work around that by using abstract members instead.
(Scala 3 lets traits have constructor parameters.)
编辑 - 这是来自 scala 邮件列表上的一个问题,我认为这里重复了。我的答案涉及提供三个不同的构造函数(即复制 Java 设计),并且不扩展类
假设每个构造函数最终创建状态
S
对象的,使用“静态”方法创建一个伴生对象来创建此状态然后创建一个采用该状态的私有构造函数和遵循主构造函数的(公共)重载构造函数
EDIT - this is from a question on the scala mailing list which I thought was duplicated here. My answer relates to providing three different constructors (i.e. replicating the Java design), and not extending the class
Assuming that each of your constructors ultimately create the state
S
of the object, create a companion object with "static" methods to create this stateThen create a private constructor taking the state and (public) overloaded constructors which defer to the primary constructor
我会选择最通用的一个(在本例中为 String),并在满足其他条件时自行进行内部转换。
尽管我承认这不是最好的解决方案,而且我觉得它有些不对劲。 :-(
I would pick the most generic one (in this case, String) and do the internal conversion yourself if it meets the other criteria.
Although I admit this is not the best solution and something strikes me as wrong about it. :-(
这是一个愚蠢的答案,可能会起作用,但如果 Java 类有太多构造函数,则可能会花费太多精力,但是:
用 Java 编写一个子类,该子类实现一个构造函数,该构造函数接受各种其他构造函数的所有输入并调用根据输入的存在或不存在(通过使用“null”或某种哨兵值)构建其超类的正确构造函数,然后在 Scala 中对该 Java 类进行子类化,并将哨兵值分配为默认参数。
This is a silly answer that would probably work somewhat but might be too much effort if the Java class has way too many constructors, but:
Write a subclass in Java that implements a constructor that takes all the inputs the various other constructors would and calls the proper constructor of its superclass based on the presence or absence of inputs (via usage of "null" or some sort of sentinel values), then subclass that Java class in Scala and assign the sentinel values as default parameters.