【发布时间】:2019-08-04 17:07:35
【问题描述】:
假设我有一个抽象类型 AA 和具体类型 XXX:
trait AA {
type A = XXX
final type B = XXX
}
在这种情况下,在 AA 的任何子类中,类型 A 和 B 都不能被覆盖,因此关键字 final 似乎是完全多余的。这种说法正确吗?
【问题讨论】:
标签: scala inheritance polymorphism abstract-type
假设我有一个抽象类型 AA 和具体类型 XXX:
trait AA {
type A = XXX
final type B = XXX
}
在这种情况下,在 AA 的任何子类中,类型 A 和 B 都不能被覆盖,因此关键字 final 似乎是完全多余的。这种说法正确吗?
【问题讨论】:
标签: scala inheritance polymorphism abstract-type
很难证明它们完全一样,但我要证明它们是相同的,除了一些无用的怪癖。
首先也是最明显的,它们给出了不同的错误信息。但这还不是全部:技术上可以覆盖A,只是不能覆盖XXX以外的任何东西:
trait A1 extends AA {
override type A = XXX // Compiles, but doesn't really do anything.
}
另一方面,你永远不能覆盖B:
trait A2 extends AA {
override type B = XXX // Does not compile.
}
再次,我要争辩说没有。在一个非常详细的answer 到问题Is it possible to override a type field 中,StackOverflow 用户0__ 指出
type T = C不可避免地修复了T,这有点对应于创建一个方法final。
和
您现在可以很容易地看到必须禁止进一步“覆盖”
T
然后解释了如果您可以将T 覆盖为不同的类型,类型系统将如何不一致。有关详细信息,请参阅该答案。
【讨论】: