Search code examples
scalatypesparametersfunction-declaration

Function arguments: upper bound vs parent class as argument?


Consider we have:

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

what is difference between those two function declarations:

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

and

def launch(fo: FlyingObject)

Great would be some examples when to use which type of declaration...

[UPDATE]

Another great example and explanation can be found there. It's another example of when you should use upper bound instead of just derived class as parameter.


Solution

  • It might be useful to have a T which is more specific than FlyingObject. Perhaps imagine you have a method

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

    Which returns a copy of the FlyingObject with a modified name. That makes this code not typecheck:

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

    Since modifyName returns a FlyingObject not a Rocket. instead:

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

    Will return a Rocket when Rocket is what is passed in.