有没有办法T在Parent中定义一个类型,T总是成为扩展类的实际类型(在这种情况下Child)?
在Parent,我想执行/宣称T要始终延伸型,仿佛我会写type T="type_of_the_extending_class"在每个实际的继承类,而无需实际写下线type T=Child1在Child1等
所以Child1的方法只接受Child1对象作为参数,Child2的方法只接受Child2对象.有没有更简单的方法来强制执行此操作?有没有办法没有type T=ChildX在每个ChildX班级写作?有没有这种样板的方法?
我一直在寻找Scala书籍的解决方案,但没有找到任何解决方案.
abstract class Parent{
type T<:Parent
def method(t:T)
}
class Child1 extends Parent{
type T=Child1
override def method(t:T)=t.child1method
def child1method=println("child1's method")
}
class Child2 extends Parent{
type T=Child2
override def method(t:T)=t.child2method
def child2method=println("child2's method")
}
Run Code Online (Sandbox Code Playgroud)
这个问题的标准解决方案是F -bounded多态(它不是Scala特定的 - 你会发现它在Java中使用,等等):
trait Parent[T <: Parent[T]] {
def method(t: T)
}
class Child1 extends Parent[Child1] {
def method(t: Child1) = println("child1's method")
}
class Child2 extends Parent[Child2] {
def method(t: Child2) = println("child1's method")
}
Run Code Online (Sandbox Code Playgroud)
作为旁注,有一些关于Scala社区中F -bounded多态性的抱怨- 例如Kris Nuttycombe说它"难以正确并导致在代码库中打字混乱",而且我个人发现我使用它更少经过几年的Scala写作后不太常见.但是,当您的程序体系结构导致您需要这种继承时,它正是该工作的正确工具.
这个问题this.type(在评论中提到的)是,它不会让你做的大部分事情你会合理要做,过于具体:
scala> abstract class Parent {
| def method(t: this.type)
| }
defined class Parent
scala> class Child1 extends Parent {
| def method(t: this.type) = println("child1's method")
| }
defined class Child1
scala> val a = new Child1
a: Child1 = Child1@19517e9a
scala> val b = new Child1
b: Child1 = Child1@5737e545
scala> a.method(b)
<console>:12: error: type mismatch;
found : b.type (with underlying type Child1)
required: a.type
a.method(b)
^
Run Code Online (Sandbox Code Playgroud)
我们唯一可以传递的论点a.method就是a它自己.
| 归档时间: |
|
| 查看次数: |
695 次 |
| 最近记录: |