我想拥有一个类B
,该类继承自一个内部类型为A
的通用类B
。具体来说,我想要这个(最小示例):
class A[T]
class B extends A[T] {
class T
}
这样编写,编译器不接受。有什么方法可以指定这种继承关系吗? (使用一些不同的语法或技巧)。
如果没有,那么什么是官方参考文件证明这是不可能的?
注释:
是的,我希望T
成为内部类。我确实希望B
的单独实例具有不兼容的类型T
。
This question考虑了相同的情况,但不询问是否/如何可行,而是要求其他方式编写相同的东西。 (至少这就是答案的解释方式。)无论如何,这个问题已有十年历史了,Scala从那以后可能就发展了。
说明::我希望B
继承自A
,而不是继承自A
的内部类,或拥有{ {1}}继承自B
。原因是我想在以下情况下使用它:A
是类型类。 A
应该提供一种快速的方法来轻松生成该类型类的新类(使用最少的样板)。我希望该类的用户执行类似的操作:B
,然后他们将能够使用类型implicit val X = createBInstance()
,它将具有类型类X.T
。到目前为止,我设法做到最好的就是支持模式A
并使用val X = createBInstance(); implicit val xTypeclass = X.typeclass
。这意味着更多样板,忘记某些东西的可能性,并且更污染命名空间(附加名称X.T
)。 (非常好奇:xTypeclass
是A
,MLValue.Converter
是B
,而QuickConverter
是X
/ Header
/。 .. in my code。)
答案 0 :(得分:3)
您可以尝试
class A {
type T
}
class B extends A {
class T
}
val b: B = new B
val t: b.T = new b.T
我将T
设置为类型成员,而不是类型参数。
在这里,一个类覆盖了一个类型。
如果您还想将T
用作类型参数,则可以引入Aux-type
object A {
type Aux[_T] = A { type T = _T }
}
,并使用类型A.Aux[T]
代替您原来的A[T]
。
现在您正在做
trait A[X]
class B {
class T
/*implicit*/ object typeclass extends A[T]
}
val b = new B
implicit val b_typeclass: b.typeclass.type = b.typeclass
val b1 = new B
implicit val b1_typeclass: b1.typeclass.type = b1.typeclass
implicitly[A[b.T]]
implicitly[A[b1.T]]
请注意,使对象typeclass
隐式变为无用。
如果您将typeclass
,b
对象而不是值制成对象,则将对象b1
隐含起来将很有用
trait A[X]
class B {
class T
implicit object typeclass extends A[T]
}
object b extends B
object b1 extends B
implicitly[A[b.T]]
implicitly[A[b1.T]]
如果您想使B
扩展A
,那么我提议将A
的类型参数替换为类型成员。 A
仍然是类型类,只是类型成员类型类而不是类型参数类型类
trait A {
type X
}
object A {
type Aux[_X] = A {type X = _X}
}
class B extends A {
type X = T
class T
}
implicit object b extends B
implicit object b1 extends B
implicitly[A.Aux[b.T]]
implicitly[A.Aux[b1.T]]