2016-12-24 91 views
1

我想理解斯卡拉中的「下界」。請找到下面的例子斯卡拉理解中的「下界」

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)允許小狗是不是一條狗,以及沒有一個超類犬,然後 ?一些真正的 用例將幫助我理解如果(animalDisplay.displayUptoDog(puppy))允許再打印,而不是更好

  2. 它 應該 [email protected] [email protected]

  3. animalDisplay.displayUptoDog(人),其中人是不是一個超類 狗然後爲什麼它被允許和打印 「[email protected]
  4. animalDisplay.displayUptoDog(工廠)其中工廠不在相同的 層次結構,t母雞爲什麼它也允許並打印 「[email protected]

讓我知道如果我錯過了一些東西

+1

'com.typeSystem.typeBound.lowerBound.Puppy'是運行時類。它沒有提及編譯時類型。您可以使用TypeTag來獲得關於編譯時類型的信息。 –

回答

0

animalDisplay.displayUptoDog(puppy)是允許的,因爲你可以施放PuppyDog,像這樣:

animalDisplay.displayUptoDog(puppy: Dog) 

現在你可能會問,什麼是方法簽名使用上T下限,如果你可以簡單地上溯造型的對象T所以f的點它的?爲了回答這個問題,我認爲最好看一個例子,下界確實有用,甚至是必要的。

一個非常常見的情況爲下限是當你想確保一些方法返回一個類型的值,與一些其他類型的常見的,例如在Option[A]有一個方法:

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

如果我們想要它的類型是AB的常見類型,唯一合理的選擇是當AB的子類型。在相反的情況下(B <: A),如果該選項爲Some[A],則不能返回A,因爲A不是B的子類型。

下面是一個例子如何工作的,當我們把它應用到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] 

正如你可以在它的行爲與預期所有的情況下看到的。當ABDogPuppy時,調用getOrElse總是會返回一個對於它們都是共同的類型,即Dog