scala:如何在自己的构造函数中获取类

时间:2010-09-27 16:56:14

标签: scala constructor

我需要访问在自己的构造函数中构造的对象的类(由于我认为与我的问题无关的各种详细原因)。

我想要这样的东西

class Foo(val i:Int)
class Bar extends Foo(this.getClass.getName.length)
val b = new Bar
println(b.i)

打印3(“Bar”.length)。但事实并非如此。如果上面的代码在某个其他对象中,则“this”指的是该对象。如果上面的代码不在某个其他对象中(仅在某个包中),编译器会抱怨

error: this can be used only in a class, object, or template
class Bar extends Foo(this.getClass.getName)
                      ^

澄清:我无法改变Foo在其体内使用val而不是其构造函数,因为Foo的API已经存在且已修复(所以,是的, i 必须是构造函数参数)。它在构造函数时需要一个整数参数,但只能通过访问Class来计算该整数。

(我知道上面的例子仍然是愚蠢和堕落。如果人们关心,我可以详细解释为什么我需要在我的真实项目中使用该课程,http://code.google.com/p/factorie

当然,正在构造的对象的类在构造期间对编译器和运行时是已知的。用什么语法可以得到它? (有没有这样的语法?如果没有,我想知道为什么。我很惊讶它似乎不是一个简单,标准的方法来获得这个。)

6 个答案:

答案 0 :(得分:8)

懒惰的val解决了这个问题:

object Early
{
    abstract class Foo { val name: String }

    class Bar extends Foo { lazy val name = getClass.getName }

    def
    main(args: Array[String]): Unit = {
        val b = new Bar
        println(b.name)
    }
}

收率:

% scala Early
Early$Bar

答案 1 :(得分:2)

不确定这是否可行。如果你喜欢黑客,你可以做到

class Bar extends Foo((new Exception).getStackTrace.apply(0).getClassName)

但是我强烈广告反对它!

答案 2 :(得分:2)

这似乎满足您的要求,而不使用惰性val并且不改变基类:

scala> class Base(val name: String)
defined class Base

scala> class Derived extends Base(classOf[Derived].getName)
defined class Derived

scala> new Derived name
res0: String = Derived

答案 3 :(得分:1)

你将不得不解释你想要这样做的动机。 name必须是Foo的构造函数参数,还是可以是抽象成员?它必须是val还是def

你可以这样做

class Foo(val name: String)
class Bar extends Foo("") {
  override val name = getClass.getName
}

new Bar().name会给Bar

但我怀疑,如果你的真正动机是已知的,那么就有更好的方法去做你真正想要的事情。

答案 4 :(得分:1)

怎么样

类Bar扩展了Foo(classOf [Bar] .getName.length)

答案 5 :(得分:0)

这个怎么样:

  class Foo(otherName: Option[String] = None) {
    val name = otherName.getOrElse(this.getClass.getName)
  }
  class Bar extends Foo()
  val b = new Bar
  println(b.name)