如果我理解正确:
"A factory constructor affords an abstract class to be
instantiated by another class, despite being abstract."
例如:
abstract class Animal {
String makeNoise(String sound);
String chooseColor(String color);
factory Animal() => new Cat();
}
class Cat implements Animal {
String makeNoise(String noise) => noise;
String chooseColor(color) => color;
}
以上允许我这样做:
Cat cat = new Animal();
var catSound = cat.makeNoise('Meow');
var catColor = cat.chooseColor('black');
print(catSound); // Meow
这也阻止了我这样做:
class Dog implements Animal {
int age;
String makeNoise(String noise) => noise;
String chooseColor(color) => color;
}
Dog dog = new Animal(); // <-- Not allowed because of the factory constructor
因此,如果我对所有这些都是正确的,我会被问到为什么动物的额外代码?
如果您打算使用只创建猫的动物的工厂构造函数,为什么不只是拥有具有所需方法/属性的Cat类?
或者,Animal类的目的是如上所述的工厂构造函数,真的是专门为Cat类设计的界面吗?
答案 0 :(得分:9)
我不认为factory
中的问题。
您的代码最初是错误的。
查看此代码并得出结论。
Locomotive locomotive = new SomethingWithSmokeFromChimney();
现在看看这段代码。
Plant plant = new SomethingWithSmokeFromChimney();
你错误地认为地球上的所有动物(甚至是狗)都是猫。
Cat cat = new Animal();
如果你想要这个。
Cat cat = new Animal();
Dog dog = new Animal();
然后(如果我正确理解你)你也想要这个。
// Cat cat = new Animal();
// Dog dog = new Animal();
Dog dog = new Cat();
P.S。
相同的错误结论,但没有factory
。
void main() {
Cat cat = new Animal();
Dog dog = new Animal();
}
class Animal {
}
class Cat implements Animal {
}
class Dog implements Animal {
}
但是这段代码(取决于文件)可能被认为是正确的。
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 {
}
抽象类的工厂构造函数可以返回(默认情况下)此抽象类的一些默认实现。
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;
}
}
答案 1 :(得分:4)
我会将Cat
视为Animal
的默认实现。
当然,您无法Dog dog = new Animal();
new Animal();
,因为Cat
会返回Dog dog = new Dog();
,但您可以Animal animal = new Dog();
或new SomeClass
编辑渴望发表评论 :)这只是另一个例子,你可以如何利用工厂构造函数。尝试将工厂构造函数视为返回对象的普通函数(顶级函数或静态类函数)。为了让类的用户不知道场景背后发生了什么,允许他像使用{{1}}的构造函数一样使用它。这就是工厂构造函数。想到的第一个用例通常是单例模式或缓存目的的实现,但也是所有其他情况,它查找类的用户,就像他只是创建一个新实例,但实际上他得到了一些构造和以更复杂的方式准备,但他不需要知道。
答案 2 :(得分:2)
工厂构造函数的一个特征是尚未在方法start处创建对象。在该方法中,您可以使用各种机制来创建对象,例如:
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();
}
}