chartman
chartman

Reputation: 182

swift subclasses in function types

Is there a way to assign a function with a parameter that is a subclass to a function variable with a parameter that is its superclass? Here is an example of what I mean:

class ClassA {}

class subclassOfA:ClassA {}

func subclassToNil(argument:subclassOfA) -> (){}

var functionVariable:(ClassA->())

funcVar = subclassToNil

This raises a type incompatibility exception.

Upvotes: 1

Views: 509

Answers (1)

andyvn22
andyvn22

Reputation: 14824

I'm afraid not--you've discovered "covariance" and "contravariance". Function types are contravariant with their parameters (arguments), which means you could supply a superclass if you wanted, but not a subclass. With return values on the other hand, function types are are covariant and could return a subclass if you'd like.

With a little thought, these rules make sense:

class ClassA {}

class SubclassOfA: ClassA {}

func subclassToNil(argument: SubclassOfA) -> ()) {}

var functionVariable: (ClassA -> ())

functionVariable = subclassToNil

functionVariable(ClassA()) //`subclassToNil` won't know what to do with this; kablooie!

However:

class ClassParent {}

class ClassA: ClassParent {}

func subclassToNil(argument: ClassParent) -> ()) {}

var functionVariable:(ClassA -> ())

functionVariable = subclassToNil

functionVariable(ClassA()) //`ClassA()` is indeed a valid `ClassParent`, so we're fine.

So it's safe to use parameters that are less specific. The reasoning for return values is very similar, and you'll see that logically, you can use ones that are more specific.

Upvotes: 2

Related Questions