'How to type the extension in Dart
I have classes called bird and dog:
class Bird extends Animal with FlyAbility, JumpAbility {
// ...
}
class Dog extends Animal with RunAbility, JumpAbility {
// ...
}
Both extend abstract class Animal and use mixin for their own ability.
Now I like to use some extensions on it to output their information:
extension BirdSheetExporter on Bird {
RowData export() {
return RowData(values: [
// type
CellData(stringValue: 'bird'),
// name
CellData(stringValue: name),
// ...
]);
}
}
extension DogSheetExporter on Dog {
RowData export() {
return RowData(values: [
// type
CellData(stringValue: 'dog'),
// name
CellData(stringValue: name),
// ...
]);
}
}
Their are also other exporter like RawTextExporter:
extension BirdRawTextExporter on Bird {
String export() {
String flyAbility = canFly ? 'can' : "can't";
return 'The bird named $name $flyAbility fly';
}
}
This is user responsibility to choose what extension they want. My question is how to give some interface for these extensions and type it?
Something like:
// extension file: raw_text_exporters.dart
abstract class RawTextExporter {
String export();
}
// I know this is not allowed
extension BirdRawTextExporter implements RawTextExporter on Bird {
// ..
}
// client file: export_animal_raw_text.dart
void exportAnimal(RawTextExporter animal) {
print(animal.export());
}
Or any suggestion for this situation? I have found some work around:
typedef rawTextExporter = String Function();
void exportAnimalByExporter(rawTextExporter exporter) {
print(exporter());
}
The reason I'm not using dynamic is code analyzer will consider the imported file not used.
import 'extensions/raw_text_exporters.dart';
// Analyzer thinks `raw_text_exporters.dart` has nothing to do with this function
void exportAnimal(dynamin animal) {
print(animal.export());
}
// type from `raw_text_exporters.dart` and it will keeps the file
void exportAnimal(RawTextExporter animal) {
print(animal.export());
}
Solution 1:[1]
I think the better solution will be dependency injection:
class Bird extends Animal with FlyAbility, JumpAbility, Exportable {
// ...
}
mixin Exportable {
T export<T>(Exporter exporter) {
return exporter.export(bird);
}
}
And the exporter's interface will be like:
abstract class Exporter<T> {
T export(Animal animal);
}
class RawTextExporter<String> {
@override
String export(Animal animal) {
final species = animal is Bird ? 'bird' : 'unknown';
return 'The $species named $name ...';
}
}
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 | 呂叿´² |
