2016-08-24 65 views
1

我有以下型號:接入領域

abstract class Shape(x1: Int, y1: Int, x2: Int, y2: Int) 

case class Line(x1: Int, y1: Int, x2: Int, y2: Int) extends Shape(x1, y1, x2, y2) 

case class Rectangle(x1: Int, y1: Int, x2: Int, y2: Int) extends Shape(x1, y1, x2, y2) 

我這樣做處理:

val shapes: scala.collection.mutable.Queue[Shape] = mutable.Queue.empty[Shape] 
    shapes.foreach(shape => { 
     (shape.x1 until shape.x2).foreach(x => if(0 <= x && x < canvas.width && 0 <= shape.y1 && shape.y1 < canvas.height) { 
     board(x)(shape.y1) = 'X' 
     }) 
    }) 

我評估每個Shape以同樣的方式,不管它是否是一個LineRectangle。然而,我無法訪問abstract class領域:

Error:(90, 14) value x1 is not a member of Shape 
     (shape.x1 until shape.x2).foreach(x => if(0 <= x && x < canvas.width && 0 <= shape.y1 && shape.y1 < canvas.height) { 
      ^

我會做一個Shapecase class,後來我就無法將其與LineRectangle延伸。

在這種情況下設計模型的最優雅方式是什麼?

我想我需要允許:

  • 基類的擴展。
  • 訪問基類的字段。
+0

您在'x's和'y'之前缺少'val's。 –

回答

3

您的問題是,構造參數不是默認情況下可用。你需要的是:

abstract class Shape(val x1: Int, val y1: Int, val x2: Int, val y2: Int) 

但是,等等!爲什麼這個工作呢?

case class Line(x1: Int, y1: Int, x2: Int, y2: Int) extends Shape(x1, y1, x2, y2) 

在工作表中:

val line = Line(1,2,3,4) 

(line.x1 until line.x2) // Works! 

答案是case cases export their constructor parameters,這意味着它們具有自動爲這些參數設置吸氣劑的方法。正常班做不是這樣做,但通過指定valvar他們會。除非您期望這些參數是可變的,否則不要使用var,這是不推薦的。

3

Shape類中,x1,y1等都不是字段。他們是構造函數參數。前綴他們val,使他們字段:

abstract class Shape(val x1: Int, val y1: Int, val x2: Int, val y2: Int) 

案例類自動做到這一點,但你必須指定val對於非例類。

2

字段x1,y1,x2y2只是構造函數參數而且是私有的。您可以添加vals來定義公共字段以及Shape(val x1,...),定義您自己的獲取者或使用case class,這會爲您提供獲取者和設置者。