问题
I have an issue to override a generic method from an abstract class.
Here is my abstract class:
abstract class A {
String getData<Type>(Type key);
}
when I created a class (B) to implement class (A) as showing below:
class B implements A {
@override
String getData<String>(String key) { //Error <= B.getData' ('String Function<String>(String)') isn't a valid override of 'A.getData' ('String Function<Type>(Type)')
return "";
}
}
Shown the below compilation error at (getData) method:
'B.getData' ('String Function(String)') isn't a valid override of 'A.getData' ('String Function(Type)'). dart(invalid_override)
And this error at the return statement:
A value of type 'String can't be returned from method 'getData' because it has a return type of 'String'.
It's confusing for me why I am getting this error related to the override when the generic type similar to return type. as when I created another class (C) with getData<int>(int key)
instead of getData<String>(String key)
everything works as expected:
class C implements A {
@override
String getData<int>(int key) {
return "";
}
}
Also with the class (B) if I deleted the return type as shown below everything will work as expected:
class B implements A {
@override
getData<String>(String key) {
return "";
}
}
Is it an issue in Dart design so I can be aware of it because this behavior does not exist in c# language for example?
DartPad Link: https://dartpad.dev/ebc7e6361d0cf1c6afad2f52ab8ebcaa
回答1:
The first method you wrote is generic over a type parameter named Type
, and has return type String
. That is, it is the function which for any type Type
returns something of type String
.
The second method, is generic over a type parameter named String
, and returns something of the type parameter type. The fact that the type parameter is named String
makes it look like you have the same return type in the first method and the second, but you don't. The first method has a return to of String
. The second method has a return type of "the type variable that was just introduced and has name String
". Those two types are unrelated, and so the override is invalid. If you rename the type variable in the second method to T
, you get the following equivalent method:
class B implements A {
@override
T getData<T>(T key) {
return "";
}
}
and it should now be clear why your override is invalid.
回答2:
The method signature
String getData<Type>(Type key);
Would more typically be written with a T
instead of Type
, since Type
already has a meaning.
String getData<T>(T key);
This signature is for a method that allows any type to be filled in for T
. This means that every subclass must have a method that allows for any type T
.
I suspect that what you want is for subclasses to be specialized to a single generic type - in that case you want to move the generic from the method level to the class level.
abstract class A<T> {
String getData(T key);
}
class B implements A<String> {
@override
String getData(String key) => '';
}
class C implements A<int> {
@override
String getData(int key) => '';
}
来源:https://stackoverflow.com/questions/61022367/dart-doesnt-override-generic-method-has-generic-parameter-type-similar-to-the