访问扩展的类的字段

时间:2016-08-24 18:26:07

标签: scala

我有以下型号:

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,无论它是Line还是Rectangle。但是,我无法访问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) {
             ^

我会将Shape设为case class,但之后我无法使用LineRectangle进行扩展。

在这种情况下,设计模型最优雅的方式是什么?

我想我需要允许:

  • 基类的扩展名。
  • 访问基类的字段。

3 个答案:

答案 0 :(得分:3)

您的问题是,默认情况下,构造参数不可用。你需要的是:

Private Sub Display_TypeOf()

Dim item As Object
Dim msgClass As String

For Each item In ActiveExplorer.Selection

    msgClass = vbCr & vbCr & "Class Is " & item.Class

    If TypeOf item Is mailItem Then
        MsgBox "Subject: " & item.Subject & vbCr & vbCr & "TypeOf Item is mailItem." & msgClass

    ElseIf TypeOf item Is ReportItem Then
        MsgBox "Subject: " & item.Subject & vbCr & vbCr & "TypeOf Item is ReportItem" & msgClass

    ElseIf TypeOf item Is PostItem Then
        MsgBox "Subject: " & item.Subject & vbCr & vbCr & "TypeOf Item is PostItem" & msgClass

    ElseIf TypeOf item Is MeetingItem Then
        MsgBox "Subject: " & item.Subject & vbCr & vbCr & "TypeOf Item is MeetingItem" & msgClass

    ElseIf TypeOf item Is AppointmentItem Then
        MsgBox "Subject: " & item.Subject & vbCr & vbCr & "TypeOf Item is AppointmentItem" & msgClass

    Else
        MsgBox "Subject: " & item.Subject & vbCr & vbCr & "TypeOf Item is not listed in this code." & msgClass

    End If

Next

End Sub

但是,等等!为什么这样呢?

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)

答案是case cases export their constructor parameters,这意味着他们已经为这些参数自动提供了getter方法。正常类执行此操作,但通过指定val line = Line(1,2,3,4) (line.x1 until line.x2) // Works! val它们将执行此操作。除非您希望这些参数是可变的,否则请勿使用var

答案 1 :(得分:3)

Shape课程中,x1y1等不是字段。它们是构造函数参数。使用val作为前缀加上字段:

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

Case类自动执行此操作,但您必须为非案例类指定val

答案 2 :(得分:2)

字段x1y1x2y2只是构造函数参数,并且是私有的。您可以添加vals来定义公共字段以及Shape(val x1,...),自定义getter或使用case class来获取getter和setter。