假设没有多重继承并且不担心与
Java的互操作性,以下两个声明是否相等?
sealed trait Foo { def x: Int }
case object Bar extends Foo { val x = 5 }
和
sealed abstract class Foo(val x: Int)
case object Bar extends Foo(5)
最佳答案 首先,对代码进行一些修改(见下文).我放弃了这个案子,因为它与此无关.我还在Foo2的构造函数中添加了val,因为在Bar2中无法访问x.
sealed trait Foo { def x: Int }
object Bar extends Foo { val x = 5 }
sealed abstract class Foo2(val x: Int)
object Bar2 extends Foo2(5)
object Main {
def main(args: Array[String]) : Unit = {
println( Bar.x )
println( Bar2.x )
}
}
Are the two following declarations equal?
我们需要定义,平等意味着什么:
>等于.一般结构:不.特征不是抽象类.特征可以没有构造函数参数,而类可以.另一方面,类或对象(此处为Bar2)只能从一个(抽象)类派生,而它可以混合多个特征.这里给出了关于特征与抽象类的良好相关性:http://www.artima.com/pins1ed/traits.html#12.7如果你需要决定一个特征或一个类.
>等于.字节代码:不.只需运行javap -v< classfile>说服自己
>等于.仅限酒吧和酒吧2:是的.两者都可以相同地访问和使用.两者都是单例,它们公开了一个从外部可读(但不可写)的成员变量x.
另外scalac -print的输出非常有用,看看发生了什么:
sealed abstract trait Foo extends Object {
def x(): Int
};
object Bar extends Object with com.Foo {
private[this] val x: Int = _;
<stable> <accessor> def x(): Int = Bar.this.x;
def <init>(): com.Bar.type = {
Bar.super.<init>();
Bar.this.x = 5;
()
}
};
sealed abstract class Foo2 extends Object {
<paramaccessor> private[this] val x: Int = _;
<stable> <accessor> <paramaccessor> def x(): Int = Foo2.this.x;
def <init>(x: Int): com.Foo2 = {
Foo2.this.x = x;
Foo2.super.<init>();
()
}
};
object Bar2 extends com.Foo2 {
def <init>(): com.Bar2.type = {
Bar2.super.<init>(5);
()
}
};
object Main extends Object {
def main(args: Array[String]): Unit = {
scala.this.Predef.println(scala.Int.box(Bar.x()));
scala.this.Predef.println(scala.Int.box(Bar2.x()))
};
def <init>(): com.Main.type = {
Main.super.<init>();
()
}
}