如何使用工厂构造函数扩展抽象 class?
How to extend an abstract class with factory constructor?
情况如下:
abstract class A {
void doSomething() => print('Do something..');
}
class B implements A {
@override
void doSomething() => print('Do something already..');
}
class C extends A {
}
我有一个摘要class A.
Class B 实现了 A。因此它覆盖了 doSomething() 方法。 Class C 扩展 A.
一切正常,直到我将工厂构造函数添加到 class A:
abstract class A {
factory A() => new B();
void doSomething() => print('Do something..');
}
这会导致我的 IDE (IntelliJ IDEA) 出错:
The generative constructor expected, but factory found
我的第一个想法是为 class C 创建构造函数,我会在其中为 A 调用工厂构造函数。这可能吗?
我在尝试扩展 Exception class 时遇到了同样的问题。它还有一个工厂构造函数:
abstract class Exception {
factory Exception([var message]) => new _ExceptionImplementation(message);
}
这就是为什么要创建我的自定义异常,我必须实现异常 class 而不是扩展它,这让我很困惑。
我还想澄清一个术语问题。
我可以说从Bclass的角度来看,A是一个接口,所以B正在实现接口A。
但是,从 C class 的角度来看,A 是一个抽象 class 所以 C 扩展了抽象 class A。这些说法正确吗?
谢谢。
德米特里。
如果 class 没有构造函数,则会隐式添加生成构造函数。如果 class 具有显式构造函数,则不会添加生成构造函数。
你有两个选择。
- 使工厂构造函数成为命名工厂构造函数并添加普通构造函数
abstract class A {
void doSomething() => print('Do something..');
factory A.name() => new B();
A();
}
- 或者命名普通构造函数并从扩展 class
中显式调用它
abstract class A {
void doSomething() => print('Do something..');
factory A() => new B();
A.protected();
}
class C extends A {
C() : super.protected();
}
尝试 DartPad
你说的对。如果你实现一个 class 它作为一个接口,如果你扩展它它作为一个基础 class.
我不知道它有用,但它解决了我的问题。而且我知道有很多解决方案可能是最糟糕的解决方案。 :) 但我想和你分享
有时后端 API returns 模型相同但值不同。
像这样。
Map<String,dynamic> map1 = {
"version": "2.16.0",
"language_1":"Dart",
"framework_1":"Flutter",
};
Map<String,dynamic> map2 = {
"version" : "10.0.1",
"language_2":"javaScript",
"framework_2":"NodeJs",
};
我需要 D
模型,因此扩展了来自 D
的其他模型
class D{
D({
this.language,
this.frameWork,
this.version,
});
String? language;
String? frameWork;
String? version;
}
扩展来自 D
的模型
class A extends D{
A();
factory A.fromJson(Map<String,dynamic> json) => C.fromJsonForA(json);
}
class B extends D{
B();
factory B.fromJson(Map<String,dynamic> json) => C.fromJsonForB(json);
}
并在其他classC
中编写factory
构造函数
class C extends D implements B,A{
C({
String? language,
String? frameWork,
String? version,
}):super(
language:language,
frameWork:frameWork,
version:version,
);
factory C.fromJsonForB(Map<String,dynamic> json){
final c = C.protected(json);
c.frameWork = json['framework_2'];
c.language = json['language_2'];
return c;
}
factory C.fromJsonForA(Map<String,dynamic> json){
final c = C.protected(json);
c.frameWork = json['framework_1'];
c.language = json['language_1'];
return c;
}
factory C.protected(Map<String,dynamic> json){
return C(
version: json["version"],
);
}
}
我用过:)
A modelA = A.fromJson(map1);
B modelB = B.fromJson(map2);
class Example {
Example._();
static printModel(D model){
print("${model.language} : ${model.frameWork} version : ${model.version}");
}
}
情况如下:
abstract class A {
void doSomething() => print('Do something..');
}
class B implements A {
@override
void doSomething() => print('Do something already..');
}
class C extends A {
}
我有一个摘要class A. Class B 实现了 A。因此它覆盖了 doSomething() 方法。 Class C 扩展 A.
一切正常,直到我将工厂构造函数添加到 class A:
abstract class A {
factory A() => new B();
void doSomething() => print('Do something..');
}
这会导致我的 IDE (IntelliJ IDEA) 出错:
The generative constructor expected, but factory found
我的第一个想法是为 class C 创建构造函数,我会在其中为 A 调用工厂构造函数。这可能吗?
我在尝试扩展 Exception class 时遇到了同样的问题。它还有一个工厂构造函数:
abstract class Exception {
factory Exception([var message]) => new _ExceptionImplementation(message);
}
这就是为什么要创建我的自定义异常,我必须实现异常 class 而不是扩展它,这让我很困惑。
我还想澄清一个术语问题。 我可以说从Bclass的角度来看,A是一个接口,所以B正在实现接口A。 但是,从 C class 的角度来看,A 是一个抽象 class 所以 C 扩展了抽象 class A。这些说法正确吗?
谢谢。
德米特里。
如果 class 没有构造函数,则会隐式添加生成构造函数。如果 class 具有显式构造函数,则不会添加生成构造函数。 你有两个选择。
- 使工厂构造函数成为命名工厂构造函数并添加普通构造函数
abstract class A {
void doSomething() => print('Do something..');
factory A.name() => new B();
A();
}
- 或者命名普通构造函数并从扩展 class 中显式调用它
abstract class A {
void doSomething() => print('Do something..');
factory A() => new B();
A.protected();
}
class C extends A {
C() : super.protected();
}
尝试 DartPad
你说的对。如果你实现一个 class 它作为一个接口,如果你扩展它它作为一个基础 class.
我不知道它有用,但它解决了我的问题。而且我知道有很多解决方案可能是最糟糕的解决方案。 :) 但我想和你分享
有时后端 API returns 模型相同但值不同。 像这样。
Map<String,dynamic> map1 = {
"version": "2.16.0",
"language_1":"Dart",
"framework_1":"Flutter",
};
Map<String,dynamic> map2 = {
"version" : "10.0.1",
"language_2":"javaScript",
"framework_2":"NodeJs",
};
我需要 D
模型,因此扩展了来自 D
class D{
D({
this.language,
this.frameWork,
this.version,
});
String? language;
String? frameWork;
String? version;
}
扩展来自 D
class A extends D{
A();
factory A.fromJson(Map<String,dynamic> json) => C.fromJsonForA(json);
}
class B extends D{
B();
factory B.fromJson(Map<String,dynamic> json) => C.fromJsonForB(json);
}
并在其他classC
factory
构造函数
class C extends D implements B,A{
C({
String? language,
String? frameWork,
String? version,
}):super(
language:language,
frameWork:frameWork,
version:version,
);
factory C.fromJsonForB(Map<String,dynamic> json){
final c = C.protected(json);
c.frameWork = json['framework_2'];
c.language = json['language_2'];
return c;
}
factory C.fromJsonForA(Map<String,dynamic> json){
final c = C.protected(json);
c.frameWork = json['framework_1'];
c.language = json['language_1'];
return c;
}
factory C.protected(Map<String,dynamic> json){
return C(
version: json["version"],
);
}
}
我用过:)
A modelA = A.fromJson(map1);
B modelB = B.fromJson(map2);
class Example {
Example._();
static printModel(D model){
print("${model.language} : ${model.frameWork} version : ${model.version}");
}
}