如何在Scala中继承抽象类的受保护/私有

如何在Scala中继承抽象类的受保护/私有,scala,class,inheritance,functional-programming,abstract-class,Scala,Class,Inheritance,Functional Programming,Abstract Class,我有一个抽象类,它有一个对象和一个表示二叉树的具体子类,用于按字典顺序对一组字符串进行排序 abstract class StringSet { def incl(x:String):StringSet def contains(x:String):Boolean def union(that:StringSet):StringSet def biggest:String // this is my new method def bigIter(acc:String):St

我有一个抽象类,它有一个对象和一个表示二叉树的具体子类,用于按字典顺序对一组字符串进行排序

abstract class StringSet {
  def incl(x:String):StringSet
  def contains(x:String):Boolean
  def union(that:StringSet):StringSet

  def biggest:String // this is my new method
  def bigIter(acc:String):String //this is my new helper method
}
object Empty extends StringSet {
  override def toString: String = "."
  def incl(x: String): StringSet = new NonEmpty(x, Empty, Empty)
  def contains(x: String): Boolean = false
  def union(that:StringSet):StringSet = that

  def biggest:String = throw new java.util.NoSuchElementException("...")
  def bigIter(acc:String):String = acc
}
class NonEmpty(elem:String, left:StringSet, right:StringSet) extends StringSet {
  def incl(x: String): StringSet = {
    if (x < elem) new NonEmpty(elem, left incl x, right)
    else if (x > elem) new NonEmpty(elem, left, right incl x)
    else this
  }
  def contains(x: String): Boolean = {
    if (x < elem) left contains x
    else if (x > elem) right contains x
    else true
  }
  def union(that:StringSet):StringSet = ((left union right) union that) incl elem

  def biggest:String =  bigIter(elem)
  def bigIter(acc:String):String = 
    if (elem < acc) left union right bigIter acc
    else left union right bigIter elem
}
抽象类StringSet{
def incl(x:字符串):字符串集
def包含(x:String):布尔值
def联合(即:StringSet):StringSet
def最大:String//这是我的新方法
def bigIter(acc:String):String//这是我的新助手方法
}
对象空扩展字符串集{
覆盖def toString:String=“”
def incl(x:String):StringSet=new非空(x,Empty,Empty)
def包含(x:String):布尔值=false
def union(that:StringSet):StringSet=that
def最大值:String=throw new java.util.NoSuchElementException(“…”)
def bigIter(附件:字符串):字符串=附件
}
类NonEmpty(elem:String,left:StringSet,right:StringSet)扩展了StringSet{
def incl(x:String):StringSet={
如果(x元素)新非空(元素,左,右,包括x)
除此之外
}
def包含(x:字符串):布尔={
如果(xelem)右侧包含x,则为else
否则是真的
}
def并集(that:StringSet):StringSet=((左并集右)并集that)包括元素
定义最大值:字符串=bigIter(elem)
def bigIter(附件:字符串):字符串=
if(元素
我想实现一个获取最大字符串的方法,只使用已经为该类创建的“函数式”方法。我使用的方法“最大”没有返回字符串的参数,它调用另一个方法“bigIter”,后者递归地调用自己,直到它遍历所有树

我的想法奏效了,但我想隐藏bigIter实现,因为用户只能看到“最大”方法。我在抽象类和具体类上使用了protected和private for bigIter,但它不起作用。我尝试在抽象类中使用private with bigIter方法,但是超类的私有方法不能被继承。我也尝试了protected,将它与超类和子类一起使用,得到了以下错误

错误:(50,39)无法在中访问StringSet类中的方法bigiter 不允许$A3.this.StringSet访问受保护的方法bigiter 因为前缀类型A$A3.this.StringSet不符合类 发生访问的A类$A3中非空 if(元素 你对如何做到这一点有什么想法吗

注: 1.在Empty上调用maxist会返回一个错误,因此我从具体类中调用“bigIter”。
2.这是我正在做的一门课程,所以我的想法是不要使用高阶列表函数

解释了当您试图访问派生类型实例中的超级类型上的方法时,编译器不高兴的原因

受保护的标识符
x
可以用作选择中的成员名称
r.x
仅当下列任一项适用时:

  • 访问权限位于定义成员的模板内,或者,如果提供了限定
    C
    ,则位于包
    C
    、类
    C
    或其配套模块内,或者
  • r
    是this和super的保留字之一,或
  • r的
    类型符合包含访问权限的类的类型实例。
最后一个项目符号基本上表示
r
,在您的例子中是
StringSet
,必须是
非空的类型

为了解决这个问题,您可以将
StringSet
的所有实现放在同一个包下,并在
bigIter
上设置
protected[package]
。例如,假设您的包名为
foo
,您可以执行以下操作:

protected[foo] def bigIter(acc: String): String 

现在它将被编译。

“我在抽象类和具体类上使用了protected And private for bigIter,但它不起作用。”什么不起作用?错误是什么?如果我正确理解您对“最大”的定义,您是否只需要查看
右侧
子集?
私有
事物不是继承的。受保护的
有什么不起作用?@Yuval Itzhakov我用你的观察更新了这个问题。感谢you@Jasper-我也使用了
保护的
。我用我得到的结果更新了问题。非常感谢。