2012-04-23 16 views
5

Considerate che abbiamo:Argomenti della funzione: limite superiore rispetto alla classe genitore come argomento?

abstract class FlyingObject; 
case class Rocket(name: String) extends FlyingObject; 

qual è la differenza tra queste due dichiarazioni di funzione:

def launch[T <: FlyingObject](fo: T) 

e

def launch(fo: FlyingObject) 

Grande sarebbe alcuni esempi quando usare quale tipo di dichiarazione. ..

[UPDATE]

Un altro grande esempio e spiegazione può essere trovato there. È un altro esempio di quando si deve usare il limite superiore anziché solo la classe derivata come parametro.

risposta

7

Potrebbe essere utile avere una T che è più specifica di FlyingObject. Forse immagina di avere un metodo

def modifyName(fo: FlyingObject, newName: String): FlyingObject = fo.copy(name=newName) 

Che restituisce una copia del FlyingObject con un nome modificato. Ciò rende questo codice non typeckeck:

val newRocket: Rocket = modifyName(oldRocket, "new name") 

Poiché modifyName restituisce un oggetto FlyingObject non un razzo. invece:.

def modifyName[T <: FlyingObject](fo: T, newName: String): T = fo.copy(name=newName) 

restituirà un razzo quando Rocket è ciò che è passato in

+0

In altre parole, è importante in particolare quando il tipo di ritorno è di tipo T. –

+2

@LuigiPlinge: forse quando è utilizzato in qualsiasi altro punto nella firma del tipo. Per voi potrebbe volere 'def confrontare [T <: FlyingObject] (uno: T, due: T)' anche – stew

4

Oltre a @stew risposta, un limite superiore potrebbe essere utile quando si utilizzano typeclasses. Ad esempio, supponiamo che tu voglia un metodo che prende due oggetti volanti e un oggetto collider che definisce come gestire la collisione con altri oggetti. Naturalmente, una collisione tra asteroidi e asteroidi non è la stessa di una collisione astronave-asteroide (esempio da manuale classico).

Si potrebbe scrivere tale metodo come:

def collide[A <: FlyingObject, B <: FlyingObject] 
    (a: A, b: B)(implicit collider: Collider[A,B]) = collider.apply(a,b) 

Poi il compilatore fornirà una corretta Collider per voi. Se invece ha scritto:

def collide(a: FlyingObject, b: FlyingObject) = a.collide(b) 

Si dovrà fare affidamento su funzionalità obect-Oriented per gestire la collisione che sarà molto difficile da scrivere e da mantenere (numero doppio della spedizione).

+0

Grande aggiunta alla risposta di @stew .. +1 – PrimosK