我们知道在Scala中,可以通过在object
关键字之后调用构造函数来初始化单个extends
的超类的实例,如下所示:
class C(val v: Int)
object Obj extends C(1)
现在,标准库中的集合以非常特殊的方式实现,将它们的构造方法委托给伴随对象。如果我希望Obj
扩展Set的某个实例怎么办?起初我天真地想写:
object Obj extends Set[Int](1, 2, 3, 4)
但是编译器抱怨道,让我想起我在这里摆出的问题。我是否误解了一些基本的Scala层次结构设计规则?
编辑:我正在揭露我的用例,以澄清为什么我觉得需要继承Set。
trait Group[A] extends Set[A] {
def add(x: A, y: A): A
val zero: A
def inverse(x: A): A
}
class CyclicElement(v: Int) {
val value = v % 4
override def equals(x: CyclicElement) = value == x.value
}
object CyclicElement {
def apply(v: Int) = new CyclicElement(v)
}
object CyclicGroup extends Set[CyclicElement](Zero, A, B, C) with Group[CyclicElement] {
override def add(x: CyclicElement, y: CyclicElement) = CyclicElement(x.value + y.value)
override val zero = CyclicElement(0)
override def inverse(x: CyclicElement) = CyclicElement(4 - x.value)
}
答案 0 :(得分:0)
编译器抱怨因为一个对象是一个单例,并且根据对象的定义,它不能在构造时获取参数。另一方面,Set是一个抽象接口,因此无论你是想创建一个对象还是一个类,都必须实现缺少的方法:
scala> class SI extends Set[Int]{}
<console>:10: error: class SI needs to be abstract, since:
it has 4 unimplemented members.
/** As seen from class SI, the missing signatures are as follows.
* For convenience, these are usable as stub implementations.
*/
// Members declared in scala.collection.GenSetLike
def iterator: Iterator[Int] = ???
// Members declared in scala.collection.SetLike
def -(elem: Int): scala.collection.immutable.Set[Int] = ???
def +(elem: Int): scala.collection.immutable.Set[Int] = ???
def contains(elem: Int): Boolean = ???
class SI extends Set[Int]{}
然而,人们可以制作一个丑陋的解决方法:
scala> object Obj extends Set[Int] {
| val content = Set[Int](1,2,3,4)
| def -(elem: Int) = content-elem
| def +(elem: Int) = content+elem
| def contains(elem: Int) = content.contains(elem)
| def iterator: Iterator[Int] = content.iterator
| }
defined object Obj
scala> Obj + 5
res1: scala.collection.immutable.Set[Int] = Set(5, 1, 2, 3, 4)
(或者你可以声明content
是一个可变的集合以保持更改)
更新:
解决方案是从Set:
的具体实现之一派生您的Objectscala> object Obj extends scala.collection.mutable.HashSet[Int]
defined object Obj
scala> Obj += 5
res4: Obj.type = Set(5)