I wrote the following (working) code and would now like to add an "octave" parameter to the constructor call for Animal subclasses, I guess so that when a new animal is created, the studio can make make appropriate adjustments. Or something. It's just a way to figure out these Dart language semantics.
The (admittedly silly but fun, yes?) idea is that an AnimalStudio instance knows what kind of Animal to add to itself based on what kind of AnimalStudio it is. Thus a CatStudio automagically adds a Cat. AnimalStudio doesn't know anything about CatStudio or Cat, so it can be part of a public API that is extended "in the wild".
There is only one animal per studio to prevent feedback.
There are three files: 1. animals.dart 2. model.dart 3. main.dart
file: animals.dart
import "dart:mirrors";
abstract class AnimalStudio {
Animal animal;
final String animalType;
String record() {
print("$animalType: ${animal.sing()} in ${animal.octave}");
}
AnimalStudio(octave) {
animal = new Animal(animalType, octave);
// print("AnimalStudio::setup(): ${animal.toString()}: $animalType");
// print("AnimalStudio::makeSound: " + animal.makeSound());
}
}
/* Here's the magic factory.
* To do:
* Get "cat", "dog", etc from mirror system.
*/
abstract class Animal {
factory Animal(String type, String octave) {
MirrorSystem libs = currentMirrorSystem();
LibraryMirror lib = libs.findLibrary(new Symbol('app.models'));
Map<Symbol, Mirror> classes = lib.declarations;
// To do: handle exception if class not found
ClassMirror cls = classes[new Symbol(type)];
InstanceMirror inst = cls.newInstance(new Symbol(''), [octave]);
return inst.reflectee;
}
}
class AnimalBase implements Animal {
final String sound; // the sound she makes when she sings
String sing() => sound;
AnimalBase(this.sound);
}
file: model.dart
library app.models;
import 'animals.dart';
class CatStudio extends AnimalStudio {
final animalType = "Cat";
CatStudio(octave) : super(octave);
}
class Cat extends AnimalBase {
final String octave;
Cat(this.octave) : super("Meow");
}
file: main.dart
import "model.dart";
void main() {
new CatStudio("C major").record();
}