0

からのメソッドを使用して独自の特性タイプを返すことができるように、特性をミックスインしたいと考えています。例えば、

> trait M { 
    trait foo {def blah = "foo" }
    def name:foo = { new foo { override def blah = "name"}}}
> trait N extends M { 
    trait bar extends foo {}
    override def name:bar = super.name.asInstanceOf[bar]}
> object t extends N { val baz = name }
> t.name
  java.lang.ClassCastException: M$$anon$1 cannot be cast to N$bar
at N$class.name(<console>:7)
at t$.name(<console>:8)
at t$.<init>(<console>:8)
at t$.<clinit>(<console>)
at .<init>(<console>:10)
at .<clinit>(<console>)
at RequestResult$.<init>(<console>:9)
at RequestResult$.<clinit>(<console>)
at RequestResult$scala_repl_result(<console>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at scala.tools.nsc.Interpreter$Request$$anonfun$loadAndRun$1$$anonfun$apply$17.apply(Interpreter.scala:988)
at scala.tools.nsc.Interpreter$Request$$anonfun$l...

私はこれについて を使用して OO のやり方で考えすぎていることを知っていasInstanceOfます。N とそのサブタイプを変更するにはどうすればよいですか?

4

1 に答える 1

2

M.nameを構築して返しますfooN.nameあなたの電話でsuper.namesuper.nameを参照するため、M.namesuper.name構築して返しますfoo。次に、それを取り、fooを呼び出します.asInstanceOf[bar]。しかし、これは意味がありません。なぜなら、あなたのコードにはbar, を構築したものはなく、 a が である間barfooafooが必ずしもであるとは限らないからbarです。

N.name本当にa を返したい場合は、明示的に a を作成して返すようbarにオーバーライドする必要があります。M.namebar

trait N extends M {
  trait bar extends foo {}
  override def name: bar ={
    val f: foo = super.name                // not what we want; it's not a `bar`
    new bar { override def blah = f.blah } // this is actually a `bar`
  }
}

今、私たちは得ます:

scala> println(t.name.blah)
name
于 2012-05-23T20:57:12.600 に答える