'In Dart, can you call another constructor from a constructor
That is, I'm trying to invoke one constructor from another, and then construct further. I can't figure out from documentation if it can be done.
Here's a contrived example, in case it helps:
class Chipmunk {
Chipmunk.named(this.name);
Chipmunk.famous() {
this.named('Chip'); // <-- What, if anything, goes here?
this.fame = 1000;
}
}
var chip = new Chimpmunk.famous();
Solution 1:[1]
There are two possible ways to do this:
class Chipmunk {
String name;
int fame;
Chipmunk.named(this.name, [this.fame]);
Chipmunk.famous1() : this.named('Chip', 1000);
factory Chipmunk.famous2() {
var result = new Chipmunk.named('Chip');
result.fame = 1000;
return result;
}
}
Chipmunk.famous1() is a redirective constructor. You can't assign properties in this one, so the constructor you are calling has to allow all the properties you want to set. That's why I added fame as an optional parameter. In this case you could make name and fame final.
Chipmunk.famous2() is a factory constructor and can just create the instance you want. In this case, fame couldn't be final (obviously it could be if you used the fame parameter in the named constructor).
The first variant would probably be the preferable one for your use case.
This is the documentation in the language spec:
A generative constructor consists of a constructor name, a constructor parameter list, and either a redirect clause or an initializer list and an optional body.
https://www.dartlang.org/docs/spec/latest/dart-language-specification.html#h.flm5xvbwhs6u
Solution 2:[2]
The init pattern could be used here : the constructor just calls an init function defined in the class.
It can have an advantage over the redirective constructor in some cases, i can think of two right now :
- if you are saving/restoring the state of your object (in this case, you just write once the restore part).
- if you are pooling (recycling) your objects and need to 'refresh' them when you revive them.
class Chipmunk {
Chipmunk.named(string newName) { nameInit(newName) };
Chipmunk.famous() {
famousInit();
}
nameInit(string newName) {
name = newName ;
}
famousInit() {
nameInit('Chip');
fame = 1000;
}
string name;
num fame;
}
var chip = new Chimpmunk.famous();
Solution 3:[3]
Another way is to use a static method that returns an instance of the same class.
It's technically not a constructor and it's not recommended by the Dart Linter, but it can help in situations where you need to choose which constructor to call depending on the value of an argument.
class Chipmunk {
Chipmunk.named(this.name, [this.fame]);
// ignore: prefer_constructors_over_static_methods
static Chipmunk withFame(int fame) {
if (fame > 100) {
return Chipmunk.named('Super Famous Chip', fame);
}
return Chipmunk.named('Chip', fame);
}
String name;
int? fame;
}
var superFamousChip = Chipmunk.withFame(110);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Dennis Kaselow |
| Solution 2 | GameAlchemist |
| Solution 3 | Thor Galle |
