Reputation: 28906
class Parent<T> {
void method(T t) {}
}
class Child extends Parent {
@override
void method(int i) {} // error: mentioned_below
void takesDynamic(dynamic d) {
takesType(d); // no error
}
void takesType(int i) {
takesDynamic(i); // no error
}
}
Error:
void Function(int) isn't a valid override of void Function(dynamic)
When I can easily pass int
to dynamic
and vice-versa in a method parameter, why do I see the error when I override method.
PS:
I am not looking for a solution which is to use extends Parent<int>
and get it working, I want to know the reason why things are treated differently when I am overriding a method vs calling regular methods.
Upvotes: 4
Views: 4878
Reputation: 89995
void Function(int x)
normally isn't a valid override of void Function(dynamic x)
because the int
version is not substitutable for the dynamic
version.
What are the allowed inputs to void Function(dynamic)
(the type of Parent<dynamic>.method
)? Anything.
What are the allowed inputs to void Function(int)
(the type of Child.method
)? Only int
s.
Such an override therefore could violate the contract of Parent<dynamic>
's interface. (For example, what if you had an instance of Child
and passed it to something that expected Parent<dynamic>
, which then invoked method('not an int')
on it?)
(Note that this is not specific to method overrides. In general, a function that takes a narrower type cannot be used where a function that takes a wider type is expected, even if the narrower type derives from the wider type.)
Dart does allow you to use the covariant
keyword to suppress the static type error and explicitly allow the override, but be aware that doing so isn't necessarily type-safe, and you would be responsible for ensuring that you don't get type errors at runtime.
Further reading: Covariance and contravariance (computer science) from Wikipedia
Upvotes: 10