Reputation: 30879
This is a Dart Generics question. This question is simpler then it seems, please keep reading.
I have:
The below code doesn't work:
import 'package:flutter/material.dart';
class SomeValue {}
class ExtendedValue extends SomeValue {}
abstract class SomeController<T extends SomeValue> extends ValueNotifier<T> {
SomeController(T value) : super(value);
factory SomeController.create() {
return ExtendedController();
}
}
class ExtendedController extends SomeController<ExtendedValue> {
ExtendedController() : super(ExtendedValue());
}
I get the error :
The return type 'ExtendedController' isn't a 'SomeController<T>', as defined by the method 'create'.
in the return ExtendedController();
line.
I then changed it to this:
import 'package:flutter/material.dart';
class SomeValue {}
class ExtendedValue extends SomeValue {}
abstract class SomeController<T extends SomeValue> extends ValueNotifier<T> {
SomeController(T value) : super(value);
factory SomeController.create() {
return ExtendedController();
}
}
class ExtendedController<S extends ExtendedValue> extends SomeController<S> {
ExtendedController() : super(ExtendedValue());
}
Still doesn't work, but now I get another error:
The constructor returns type 'ExtendedValue' that isn't of expected type 'S'.
this time in the super(ExtendedValue());
line.
Upvotes: 7
Views: 4773
Reputation: 657228
An explicit cast fixes it:
factory SomeController.create() {
return ExtendedController() as SomeController<T>;
}
https://groups.google.com/a/dartlang.org/forum/#!topic/misc/bVRHdagR8Tw
alternatively you can use
static create() {
return ExtendedController() as SomeController<T>;
}
With optional new
there isn't a difference anymore.
Upvotes: 3
Reputation: 21728
Let's take the first error:
The return type 'ExtendedController' isn't a 'SomeController<T>', as defined by the method 'create'.
It is telling ExtendedController
is not an expected return type from create
method as per definition.
create
is a factory method here it and expects the return type to be SomeController
factory SomeController.create() {
return SomeController();
}
We cannot change like this also as SomeController
is an abstract class.
So, I moved the factory
method to ExtendedController.
class SomeValue {}
class ExtendedValue extends SomeValue {}
abstract class SomeController<T extends SomeValue> extends ValueNotifier<T> {
SomeController(T value) : super(value);
}
class ExtendedController extends SomeController {
ExtendedController(ExtendedValue value) : super(value);
factory ExtendedController.create() {
return ExtendedController(ExtendedValue());
}
}
Hope my explanation helps up to some extent.
Upvotes: 1