Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Scala中创建和访问抽象类字段_Scala_Class_Abstract Class - Fatal编程技术网

在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

我是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(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)))