首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >定义方法以返回扩展它的类的类型

定义方法以返回扩展它的类的类型
EN

Stack Overflow用户
提问于 2011-03-17 05:02:54
回答 3查看 9.1K关注 0票数 24

我希望能够做这样的事情:

代码语言:javascript
复制
trait A {
  def f(): ???_THE_EXTENDING CLASS
}
class C extends A {
  def f() = self
}
class D extends A {
  def f() = new D
}
class Z extends D {
  def f() = new Z
}

在上面的代码中,下面的代码将无法编译

代码语言:javascript
复制
class Bad1 extends A {
  def f() = "unrelated string"
}
class Bad2 extends A {
  def f() = new C // this means that you can't just define a type parameter on
                  // A like A[T <: A] with f() defined as f: T
}
class Bad3 extends D // f() now doesn't return the correct type

这种关系有名字吗?它是如何在Scala中注释/实现的?

编辑

正如您所看到的,以下是一种工作方式:

代码语言:javascript
复制
scala> trait A {
     | def f: this.type 
     | }
defined trait A

scala> class C extends A {
     | def f = this 
     | }
defined class C

scala> class D extends A {
     | def f = new D
     | }
<console>:7: error: type mismatch;
 found   : D
 required: D.this.type
       def f = new D
               ^

有没有办法绕过这一点?

编辑2

使用第二个系统,我可以这样做,这很好地达到了D类的定义:

代码语言:javascript
复制
scala> trait A[T <: A[T]] { def f(): T }
defined trait A
// OR
scala> trait A[T <: A[T]] { self: T =>
     | def f(): T
     | }

scala> class C extends A[C] { def f() = new C }
defined class C

scala> class D extends C
defined class D

scala> (new D).f
res0: C = C@465fadce
EN

回答 3

Stack Overflow用户

发布于 2011-03-17 05:59:32

恐怕无法从扩展类中知道扩展类是什么。

与您想要的最接近的是类似于C++的奇特循环模板模式(CRTP)。

代码语言:javascript
复制
trait A[T <: A[T]] {
  def f(): T;
}

class C extends A[C] {
  def f() = new C
}

class D extends A[D] {
  def f() = new D
}
票数 15
EN

Stack Overflow用户

发布于 2011-03-17 06:09:37

您可以做的一件事是返回类型this.type

代码语言:javascript
复制
trait A {
  def f(): this.type
}

class C extends A {
  def f() = this
}

class D extends A {
  def f() = this
}

class Z extends D {
  override def f() = this
  def x = "x"
}

println((new Z).f().x)

这对构建者很有用。

票数 6
EN

Stack Overflow用户

发布于 2011-03-17 06:59:43

这是另一种可能的解决方案。它是self类型+ type参数的组合:

代码语言:javascript
复制
trait A[T <: A[T]] { self: T =>
  def f(): T
}

class Z extends A[Z] {
  override def f() = new Z
  def x = "x"
}

println((new Z).f().x)

您可以在此处找到有关此解决方案的更多信息:

scala self-type: value is not a member error

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5331722

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档