[英]Scala trait inheritance strange behavior
有人可以解釋為什么這個程序打印0而不是4?
trait Rectangular {
def width: Int
def height: Int
val area = width * height
}
case class Square(val size: Int) extends Rectangular {
val width = size
val height = size
}
print(Square(2).area)
但是當我使vals懶惰時它會起作用
trait Rectangular {
def width: Int
def height: Int
val area = width * height
}
case class Square(val size: Int) extends Rectangular {
lazy val width = size
lazy val height = size
}
print(Square(2).area)
這是Scala構造val
成員的方式的一個不幸的問題。
trait Rectangular {
def width: Int
def height: Int
val area = width * height
}
case class Square(val size: Int) extends Rectangular {
val width = size
val height = size
}
在內部,Scala使Square
私有成員稱為width
和height
。 它將它們初始化為零。 然后,在Square
構造函數中,它設置它們。 基本上,它做了一些接近這個Java代碼的東西。
public abstract class Rectangular {
private int area;
public Rectangular() {
area = width() * height();
}
public abstract int width();
public abstract int height();
public int area() { return area; }
}
public class Square extends Rectangular {
private int width, height;
public Square(int size) {
Rectangular();
width = size;
height = size;
}
public int width() { return width; }
public int height() { return width; }
}
請注意,在Square
構造函數之前調用Rectangular
構造函數,因此area
在設置之前會看到默認的零width
和height
值。 正如您已經發現的那樣,使用lazy val
解決問題。
trait Rectangular {
def width: Int
def height: Int
val area = width * height
}
case class Square(val size: Int) extends Rectangular {
lazy val width = size
lazy val height = size
}
或者,您可以使用早期初始化程序語法強制以正確的順序寫入值。
trait Rectangular {
def width: Int
def height: Int
val area = width * height
}
case class Square(val size: Int) extends {
val width = size
val height = size
} with Rectangular
lazy val
解決方案通常是優選的,因為它可以減少道路上的意外。
有關更多信息,請參閱有關此特定主題的Scala常見問題解答 。
問題是你的特質中的val在你的類的val之前被初始化了。
因此,當您調用構造函數時,第一個area
將被初始化。 它將其值設置為width * height
。 width
和height
都沒有初始化,因此它們的值為零。 這意味着area = 0 * 0 = 0
。
之后, width
和height
設置為size
的值,但此時對於區域來說太晚了。
它適用於lazy val
因為lazy vals檢查它們是否在訪問時被初始化,如果沒有則初始化它們。 常規val沒有這樣的檢查。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.