在Scala中创建和访问抽象类字段
我是Scala新手,在一些相当简单的问题上遇到了一些困难。我正在实现一个简单的二叉树来存储整数,如下所示:在Scala中创建和访问抽象类字段,scala,class,abstract-class,Scala,Class,Abstract Class,我是Scala新手,在一些相当简单的问题上遇到了一些困难。我正在实现一个简单的二叉树来存储整数,如下所示: abstract class IntSet { def incl(x: Int): IntSet def contains(x: Int): Boolean } class Empty extends IntSet { def contains(x: Int): Boolean = false def incl(x: Int): IntSet = new NonEmpty
abstract class IntSet {
def incl(x: Int): IntSet
def contains(x: Int): Boolean
}
class Empty extends IntSet {
def contains(x: Int): Boolean = false
def incl(x: Int): IntSet = new NonEmpty(x, new Empty, new Empty)
}
class NonEmpty(elem: Int, left: IntSet, right: IntSet) extends IntSet {
val head = elem
val leftChild = left
val rightChild = right
def contains(x: Int): Boolean =
if (x < elem) left contains x
else if (x > elem) right contains x
else true
def incl(x: Int): IntSet =
if (x < elem) new NonEmpty(elem, left incl x, right)
else if (x > elem) new NonEmpty(elem, left, right incl x)
else this
}
val my_intset = new NonEmpty(5, new Empty, new Empty)
my_intset.head
val new_intset = my_intset.incl(10)
new_intset.head
抽象类IntSet{
def incl(x:Int):IntSet
def包含(x:Int):布尔值
}
类Empty扩展了IntSet{
def contains(x:Int):布尔值=false
def incl(x:Int):IntSet=new NonEmpty(x,new Empty,new Empty)
}
类NonEmpty(elem:Int,left:IntSet,right:IntSet)扩展了IntSet{
瓦尔头=元素
val leftChild=左
val rightChild=right
def包含(x:Int):布尔值=
如果(xelem)右侧包含x,则为else
否则是真的
def incl(x:Int):IntSet=
如果(x元素)新非空(元素,左,右,包括x)
除此之外
}
val my_intset=new NonEmpty(5,new Empty,new Empty)
我的头
val new_intset=my_intset.incl(10)
新intset.head
遇到了两个问题:首先,我无法访问这些类的任何元素,因此实现了字段head
,leftchild
,和righchild
。这使得my_intset
可以访问它们。但是,一旦调用了incl
,对象的类型就会改变,new\u intset
现在是intset
,使我无法再次访问其中的元素。我如何确保这些字段在任何时候都可以访问
其次,我对调用
incl
时对象的类型发生变化感到不安。从用户的角度来看,我觉得这两个对象都是IntSet
的实例,这就是我的意图。我担心是对的?有没有办法控制这种行为?在Scala中,可以利用和操作这些类型
我们可以稍微修改一下你的例子。我们将创建一个sealed trait
,它定义了类型的基本结构:
sealed trait IntSet {
val head: Option[Int]
val left: IntSet
val right: IntSet
def incl(x: Int): IntSet
def contains(x: Int): Boolean
}
现在我们将添加具体的案例对象/类,这些对象/类继承:
case class NonEmpty(head: Option[Int], left: IntSet, right: IntSet) extends IntSet {
def contains(x: Int): Boolean = {
if (x < head.getOrElse(0)) left contains x
else if (x > head.getOrElse(0)) right contains x
else true
}
def incl(x: Int): IntSet = {
if (x < head.getOrElse(0)) NonEmpty(head, left incl x, right)
else if (x > head.getOrElse(0)) NonEmpty(head, left, right incl x)
else this
}
}
case object Empty extends IntSet {
override val head: Option[Int] = None
override val left: IntSet = Empty
override val right: IntSet = Empty
def contains(x: Int): Boolean = false
def incl(x: Int): IntSet = NonEmpty(Some(x), Empty, Empty)
}
此外,当我们想要对IntSet
进行操作时,我们可以对其进行模式匹配,以处理底层的具体类型:
def isEmpty(intSet: IntSet): Boolean = intSet match {
case Empty => true
case NonEmpty(_, _, _) => false
}
作为旁注,我使用了选项[Int]
来表示头部。如果您不介意将的head
设置为空
值0,则可以使用Int
如果你想要一个类似的例子,我建议你
代数仅定义您操作的类型的另一个示例如下所示:
sealed trait BinaryTree
case class Node(value: Int, left: BinaryTree, right: BinaryTree) extends BinaryTree
case object Empty extends BinaryTree
def incl(tree: BinaryTree, x: Int): BinaryTree = {
tree match {
case Node(value, left, right) =>
if (x < value) Node(value, incl(left, x), right)
else if (x > value) Node(value, left, incl(right, x))
else tree
case Empty => Node(x, Empty, Empty)
}
}
收益率:
Node(0,Node(1,Empty,Empty),Node(2,Empty,Node(3,Empty,Empty)))
def main (args: Array[String] ): Unit = {
val n = Node(0, Node(1, Empty, Empty), Node(2, Empty, Empty))
val x = incl(n, 3)
println(x)
}
Node(0,Node(1,Empty,Empty),Node(2,Empty,Node(3,Empty,Empty)))