我正在尝试下面的Java代码在scala中转换它但我无法从scala中的子类调用超类构造函数.我该如何解决这个问题.
//java code
class A
{
public A(String a){}
public A(String a, int b){}
}
class B extends A
{
public B(String c){
super(c);
}
public B(String c,int d){
super(c,d);//how to do this in scala
}
}
Run Code Online (Sandbox Code Playgroud)
Cre*_*eos 13
您将从构造函数的一些基本scala教程中受益,但让我试试.简而言之 - 你无法在scala中完全执行此操作.
class Foo(x: Int, y: Int, s: String) extends Bar(s)您可以在Foo中定义另一个构造函数,但它必须链接回其主构造函数def this(x: Int) = this(x, 0, "")extends Bar(...)类定义的部分中(因此,您只能将其作为定义主构造函数和类的一部分).使用与上面相同的示例,如果您有class Bar(s: String)并且扩展它class Foo(val x: Int, val y: Int, s: String) extends Bar(s),则在声明要扩展它的同时调用超级构造函数,即extends Bar(s)部分.因此,鉴于上述两点,由于所有构造函数必须链接到类的单个主构造函数并且单个主构造函数只调用单个超级构造函数,因此无法在Scala中完全转换Java示例.但是,你可以通过这样做获得相同的东西.
final class Foo(x: Int, y: Int, s: String) extends Bar(s) {
def this(x: Int) = this(x, 1/*Foo's default*/, ???/*you likely want the same default that super would use, in this case "bar", see below*/)
}
class Bar(s: String) {
def this() = this("bar")
}
Run Code Online (Sandbox Code Playgroud)
实际上,在scala中你首先链接,然后应用所有默认值,然后你调用super而不是从你的各种构造函数中调用super,就像在Java中一样.
您可以将超级构造函数默认值存储在协同服务器中,object Bar { defaultString: String = "bar" }并使用in Foo和in 两者Bar来确保impl保持同步.这看起来很笨重,但实际上更安全,因为它确保了相同的行为,无论你调用哪个构造函数,而在java中你可能有不同的默认值(这是有问题的).这里是:
final class Foo(x: Int, y: Int, s: String) extends Bar(s) {
def this(x: Int) = this(x, 1/*Foo's default*/, Bar.defaultString)
}
class Bar(s: String) {
def this() = this(Bar.defaultString)
}
object Bar {
protected val defaultString: String = "bar"
}
Run Code Online (Sandbox Code Playgroud)
但请注意,在scala中 - 由于已建立的伴随对象和应用方法的设施(您可以将它们视为Java中的静态工厂方法),我不会看到人们使用大量非主要构造函数.它们使用了几种apply方法,因此您的主构造函数通常会获取所有可能的参数.另一种选择是让它们使用默认值.因此,您很少需要非主要构造函数和链接.
在相关的说明中,如果您有直接传递给超类的构造函数参数,请注意不要包括val因为它会复制子类中的变量,并增加内存占用.这有点微妙.另外,如果您碰巧在主ctor中引用了一个没有val的变量,但是从超类中看不到它,编译器会认为它有一个private[this] val修饰符,并且还将它保存为一个字段.子类.让我来说明一下
class A(val name: String, val counter: Int)
class B(
val b: Int /*this is B's field by design*/,
str: String/*meant to be passed to super, so no val*/,
i: Int /*meant to be passed to super, so no val*/) extends A(str, i) {
def firstLetterOfName = str.head // Oops, I should have done name.head
}
Run Code Online (Sandbox Code Playgroud)
由于我所提到的str是B的构造函数而不是nameA的字段,因此str将得到一个默认private[this] val修饰符并将保存为B字段,从而复制name超类中的字段A.现在我们有两个重复的字段.
| 归档时间: |
|
| 查看次数: |
4003 次 |
| 最近记录: |