2016-09-24 2 views
1

は、これらのクラスと変数を考える:サブタイプを安全にキャストできますか?

abstract class Base[T <: Base[_]] { 
    val self: T 
    def me(): T = self 
} 

class Derived extends Base[Derived] { 
    lazy val self = this 
    def whoAmI() = "Im derived" 
} 

val d = new Derived 

私は無事d.foo().whoAmI()

を呼び出すことができますがしかし、これはまた、タイプセーフでしょうか?

abstract class Base[T <: Base[_]] { 
    def me(): T = this.asInstanceOf[T] 
} 

class Derived extends Base[Derived] { 
    def whoAmI() = "Im derived" 
} 

私は他のクラスが派生から延び、キャストが

答えて

5

を爆破することがタイプセーフされていないエッジケースを考えています。コンパイルするためにasInstanceOfを使用する必要がある場合は、答えは圧倒的に "いいえ"になります。サブタイプにキャストすることが「安全」である唯一の時間は、サブタイプが1つだけの場合です。それ以外の場合、保証はできません。 。 - 彼らは両方のBaseを拡張するだけで

abstract class Base[T <: Base[_]] { 
    def me(): T = this.asInstanceOf[T] 
} 

class A extends Base[A] 
class B extends Base[A] 

scala> val b = new B 
b: B = [email protected] 

scala> b.me 
java.lang.ClassCastException: B cannot be cast to A 
    ... 33 elided 

我々が拡張しているBaseTは、我々が作成しているサブタイプと同じでなければならないという制限はありません。

は、この例で考えてみましょうAおよびBは両方ともBase[_]ですが、BAではないため、Aへのキャストは安全ではありません。

これはBase内に自己タイプを導入することで簡単に修正できます。Tも必要です。次に、thisTであり、キャストする必要はありません。

abstract class Base[T <: Base[_]] { this: T => 
    def me(): T = this 
} 

これはコンパイルされません:

完璧な理にかなっている
scala> class B extends Base[A] 
<console>:12: error: illegal inheritance; 
self-type B does not conform to Base[A]'s selftype A 
     class B extends Base[A] 
        ^
+0

、おかげで –

関連する問題