新しいジェネリッククラスを構築したいとしNovel[A]
ます。このクラスには多くの便利なメソッドが含まれているため(おそらくコレクションの一種である可能性があります)、サブクラス化する必要があります。ただし、元の型ではなく、サブクラスの型をメソッドが返すようにする必要があります。Scala 2.8では、そのクラスのメソッドが元のサブクラスではなく、関連するサブクラスを返すために必要な最小限の作業はどれくらいですか?例えば、
class Novel[A] /* What goes here? */ {
/* Must you have stuff here? */
def reverse/* What goes here instead of :Novel[A]? */ = //...
def revrev/*?*/ = reverse.reverse
}
class ShortStory[A] extends Novel[A] /* What goes here? */ {
override def reverse: /*?*/ = //...
}
val ss = new ShortStory[String]
val ss2 = ss.revrev // Type had better be ShortStory[String], not Novel[String]
共変したい場合、この最小量は変わりますNovel
か?
(2.8コレクションは、とりわけこれを行いますが、より派手な(そして便利な)方法でリターンタイプを操作します-問題は、このサブタイプ(常にリターンサブタイプ)のみが必要な場合に、フレームワークをどのように回避できるかです。特徴。)
編集:上記のコードでコピーを作成すると仮定しreverse
ます。インプレース修正を行ってから自分自身を返す場合は、を使用できますthis.type
が、コピーがではないため、それは機能しませんthis
。
Arjanは、次の解決策を提案する別の質問にリンクしました。
def reverse: this.type = {
/*creation of new object*/.asInstanceOf[this.type]
}
これは基本的に、必要なものを取得するための型システムにあります。しかし、これは実際には解決策ではありません。型システムに嘘をついたので、コンパイラーは、私たちが思ったときに本当に戻ってくることを確認するのに役立ちませんShortStory
。(たとえばreverse
、コンパイラーを満足させるために上記の例でオーバーライドする必要はありませんが、型は私たちが望んでいたものではありません。)