2016-12-24 12 views
1

私はスカラの「下限」を理解しようとしています。 animalDisplay.displayUptoDog(puppy)が許可されている理由子犬は、その後、同様に 犬のスーパークラス犬ではないではないのでScalaの理解で「下限」

class Animal 
class Dog extends Animal 
class Puppy extends Dog 
class Human extends Animal 
class Plant 
class AnimalDisplay{ 
    def displayUptoDog [T >: Dog](t: T){ 
    println(t) 
    } 

    def displayUptoAnimal [T >: Animal](t: T){ 
    println(">>"+t.getClass()) 
    } 

} 

object ScalaLowerBoundsTest { 
    def main(args: Array[String]) {  
    val animal = new Animal 
    val dog = new Dog 
    val puppy = new Puppy 
    val human=new Human 
    val plant = new Plant 
    val animalDisplay = new AnimalDisplay 

    println("Upto Animal") 
    animalDisplay.displayUptoAnimal(animal) 
    animalDisplay.displayUptoAnimal(dog) 
    animalDisplay.displayUptoAnimal(puppy) 
    animalDisplay.displayUptoAnimal(human) 
    animalDisplay.displayUptoAnimal(plant) 

println("Upto Dog") 
    animalDisplay.displayUptoDog(animal)  
    animalDisplay.displayUptoDog(dog) 
    animalDisplay.displayUptoDog(puppy) 
// prints: [email protected] 
    animalDisplay.displayUptoDog(human) 
//print:[email protected] 
    animalDisplay.displayUptoDog(plant) 
//prints:[email protected] 
    } 
} 

私の質問は

  1. ある下記の例を見つけてください!それは(animalDisplay.displayUptoDog(puppy))はなく人間がのスーパークラス ない [email protected]

  2. animalDisplay.displayUptoDog(人間)のそれ べき 印刷[email protected]許可されている場合は、いくつかの本当の ユースケースは、私はより良い

  3. を理解するのに役立ちますなぜ犬が許可され、印刷されているのですか? "[email protected]"

  4. animalDisplay.displayUptoDog(plant)ここで植物は同じ の階層にはありませんあなたがPuppyをキャストすることができますので、それはまた、許可され、 「[email protected]

は、私はいくつかのこと

+1

'com.typeSystem.typeBound.lowerBound.Puppy'は実行時クラスです。コンパイル時のタイプについては何も言わない。 'TypeTag'を使って、コンパイル時の型について知ることができます。 –

答えて

0

animalDisplay.displayUptoDog(puppy)をしないのですなら、私に教えてくださいを印刷している理由編は、許可されていますこのようなDogに:

animalDisplay.displayUptoDog(puppy: Dog) 

あなたが求めることができる、あなたは、単にそれをF Tにオブジェクトをアップキャストすることができた場合、メソッドのシグネチャにT上下限を使用してのポイントは何ですかその?その質問に答えるためには、下限が本当に有用であるか、必要でさえある例を見ることが最善だと思います。あなたには、いくつかの方法がOption[A]では、たとえば、他のいくつかのタイプと共通である型の値を返すメソッドがあることを確認したいとき下限ため

1つの非常に一般的な使用例は次のとおりです。

def getOrElse[B >: A](default: ⇒ B): B 

ABで共通のタイプが必要な場合は、AのサブタイプがBの場合のみ妥当なオプションがあります。反対の場合(B <: A)、ABのサブタイプではないため、そのオプションがSome[A]の場合はAを返すことができませんでした。ここで

たちはDogクラス階層に適用する場合、それがどのように機能するかの例です:

val d1 = Some(dog).getOrElse(puppy) 
d1: Dog = [email protected] 

val d2 = (None: Option[Dog]).getOrElse(puppy) 
d2: Dog = [email protected] 

val d3 = Some(puppy).getOrElse(dog) 
d3: Dog = [email protected] 

val d4 = (None: Option[Puppy]).getOrElse(dog) 
d4: Dog = [email protected] 

あなたは予想通り、すべてのケースでは、振る舞い見ることができるように。 ABDogまたはPuppyのいずれかである場合は、getOrElseを呼び出すと、常にどちらも共通のタイプのDogが返されます。