If I am understanding correctly:
\"A factory constructor affords an abstract class to be
instantiated by another class, despite being abstract.\"
I don't think that the problem in the factory
.
Your code initially was wrong.
Look at this code and make your conclusions.
Locomotive locomotive = new SomethingWithSmokeFromChimney();
Now look at this code.
Plant plant = new SomethingWithSmokeFromChimney();
You mistakenly believe that all animals on the earth (even the dogs) are cats.
Cat cat = new Animal();
If you want this.
Cat cat = new Animal();
Dog dog = new Animal();
Then (if I correctly understand you) you also want this.
// Cat cat = new Animal();
// Dog dog = new Animal();
Dog dog = new Cat();
P.S.
The same wrong conclusions but without factory
.
void main() {
Cat cat = new Animal();
Dog dog = new Animal();
}
class Animal {
}
class Cat implements Animal {
}
class Dog implements Animal {
}
But this code (depending on documenation) may be considered correct.
void main() {
Cat cat = new Animal("cat");
Dog dog = new Animal("dog");
}
abstract class Animal {
factory Animal(String type) {
switch(type) {
case "cat":
return new Cat();
case "dog":
return new Dog();
default:
throw "The '$type' is not an animal";
}
}
}
class Cat implements Animal {
}
class Dog implements Animal {
}
The factory constructor of the abstract class can return (by default) some default implementation of this abstract class.
abstract class Future<T> {
factory Future(computation()) {
_Future result = new _Future<T>();
Timer.run(() {
try {
result._complete(computation());
} catch (e, s) {
result._completeError(e, s);
}
});
return result;
}
}
The one characteristic of a factory constructor is that the object is not already created at the method start. In the method you can have various mechanisms to create the object, like for example:
abstract class Animal {
String makeNoise(String sound);
String chooseColor(String color);
factory Animal() {
var random = new math.Random();
if (random.nextBool() == true)
return new Cat();
else
return new Dog();
}
}
I would see Cat
as the default implementation of Animal
.
Of course you can't do Dog dog = new Animal();
because new Animal();
returns a Cat
but you can do Dog dog = new Dog();
or Animal animal = new Dog();
EDIT to long for a comment
:) This is just one other example how you can utilize factory constructor. Try to see the factory constructor as a normal function (top level function or static class function) that returns an object. To make the user of the class unaware of what is going on behind the scene allow him to use it like a constructor with new SomeClass
. That is what a factory constructor is. The first use cases that comes to mind are usually an implementation for the singleton pattern or for caching purposes but also all other cases where it looks for the user of the class as if he just creates a new instance but in fact he gets something constructed and prepared in a way that is more complicated but he needs not to be aware of.