0

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();
}
Tom Russell
  • 1,015
  • 2
  • 10
  • 29
  • This is the same question. Please improve the other question instead of asking the same question again. Please demonstrate exactly what you want to accomplish **without** reflection/mirrors to make clear what you want to accomplish. Doing it with mirrors in only a small additional step. – Günter Zöchbauer Nov 06 '15 at 08:06
  • Sorry about that. But I am not getting an answer I can understand, so I guess I'll keep asking in different ways until someone understands what I'm getting at. – Tom Russell Nov 06 '15 at 08:18
  • This is a very simple question which is made very complicated with a lot of noise and leaving out bits that are required to understand how the parts are related. Show the full code of a *simple* example that allows to reproduce what you want to accomplish *without reflection* and then I can show you how to do it with reflection. You can also create a DartPad http://dartpad.dartlang.org with fully running code (again no need to use reflection/mirrors yet). Then we have a good starting point to discuss troubles you run into. Still, please improve your previous question. – Günter Zöchbauer Nov 06 '15 at 08:25
  • I edited the example above into a working state. The addition of the AnimalBase class allows for the addition of the generative constructor; otherwise Cat must directly implement Animal. This means there's no "Cat(arg) : super(arg)". At least that is my current understanding. – Tom Russell Nov 15 '15 at 07:50
  • Please see the discussion at http://stackoverflow.com/questions/33664975 for more info on implementing an abstract class containing a factory. – Tom Russell Nov 15 '15 at 07:53

0 Answers0