我有以下型号:
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
,但之后我无法使用Line
和Rectangle
进行扩展。
在这种情况下,设计模型最优雅的方式是什么?
我想我需要允许:
答案 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
课程中,x1
,y1
等不是字段。它们是构造函数参数。使用val
作为前缀加上字段:
abstract class Shape(val x1: Int, val y1: Int, val x2: Int, val y2: Int)
Case类自动执行此操作,但您必须为非案例类指定val
。
答案 2 :(得分:2)
字段x1
,y1
,x2
和y2
只是构造函数参数,并且是私有的。您可以添加vals
来定义公共字段以及Shape(val x1,...)
,自定义getter或使用case class
来获取getter和setter。