为什么我的 sub class that implements/extends a parent class 在 Dart Flutter 中不被识别为父 class 的子类型?
Why isn't my sub class that implements/extends a parent class recognized as a sub type of the parent class in Dart Flutter?
我有实现 IIdentified
class 的 ProjectModel
class。但是在运行时,我得到一个错误,指出 ProjectModel
不是 IIdentified
的子类型,尽管它实现了它。我也曾尝试在 ProjectModel
中使用 extend
而不是 implements
但这也无济于事。我如何在 Dart Flutter 中使用接口,以便 Widget 可以具有满足特定接口或契约的通用类型?
Parent class IIdentified
我像接口一样使用:
abstract class IIdentified {
String id;
String name;
}
子 class 实现(也尝试扩展)父 class IIdentified
:
class ProjectModel implements IIdentified {
String id;
DateTime created;
DateTime updated;
bool hasMileage;
bool hasAllowance;
bool hasTravelTime;
String name;
String description;
DateTime startDate;
DateTime endDate;
DateTime completed;
double estimatedTime;
double absentTime;
double presentTime;
Status status;
String companyId;
String customerId;
ProjectModel(
{this.id,
this.created,
this.updated,
this.hasMileage,
this.hasAllowance,
this.hasTravelTime,
this.name,
this.description,
this.startDate,
this.endDate,
this.completed,
this.estimatedTime,
this.absentTime,
this.presentTime,
this.status,
this.companyId,
this.customerId});
我收到以下错误消息,我尝试传递的函数中的 ProjectModel
参数不算作 IIdentified
:
The following _TypeError was thrown building LoaderDropdownButton<ProjectModel>(dirty, dependencies: [MediaQuery], state: LoaderDropdownButtonState<IIdentified>#f2031):
type '(ProjectModel) => void' is not a subtype of type '(IIdentified) => void'
通用小部件只接受类型 T extends IIdentified
:
class LoaderDropdownButtonState<T extends IIdentified> extends State<LoaderDropdownButton<T>> {
double displayWidth;
double displayHeight;
@override
void initState() {
init();
super.initState();
}
@override
Widget build(BuildContext context) {
setDisplayDimensions();
return Container(
padding: EdgeInsets.only(left: 25),
color: widget.enableSelect ? themeConfig.dropButtonBg : themeConfig.dropButtonDisabledBg,
child: Theme(
data: ThemeData(canvasColor: Color(0xFFC5C5C5)),
child: DropdownButtonHideUnderline(
child: new DropdownButton<T>(
hint: Row(
children: <Widget>[
Expanded(
flex: 10,
child: Container(
alignment: Alignment.center,
margin: EdgeInsets.only(top: 2),
child: Text(
widget.text,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: widget.enableSelect
? themeConfig.dropButtonFg
: themeConfig.dropButtonDisabledFg,
fontSize: displayWidth * 0.045,
),
),
),
),
Flexible(
flex: 2,
child: Container(
margin: EdgeInsets.only(top: 5),
child: Icon(
Icons.keyboard_arrow_down,
color: widget.enableSelect
? themeConfig.dropButtonFg
: themeConfig.dropButtonDisabledFg,
),
),
)
],
),
iconSize: 0,
isExpanded: true,
items: buildItems(),
onChanged: widget.onChange),
),
),
);
}
void init() {
displayWidth = 1;
displayHeight = 1;
}
setDisplayDimensions() {
if (displayWidth == 1) displayWidth = MediaQuery.of(context).size.width;
if (displayHeight == 1) displayHeight = MediaQuery.of(context).size.height;
}
List<DropdownMenuItem<T>> buildItems() {
return widget.data.map((dataItem) {
return DropdownMenuItem<T>(
value: dataItem,
child: Text(dataItem.name),
);
}).toList();
}
}
为什么 ProjectModel
在 implements/extends 时不作为 IIdentified
通过?您如何在通用小部件中使用 interfaces/contracts?
谢谢!
I get the following error that the ProjectModel parameter in a function I'm trying to pass, does not count as being an IIdentified.
我不认为你真的粘贴了那个函数,但我仍然可以正确地猜到发生了什么。问题是您创建了一个带有签名的函数:
(ProjectModel) => void
并想将它用作需要 (IIdentified) => void
的参数。当我们谈论继承和方法参数时,这是一个常见的问题,因为它看起来有点落后。
但是,问题是如果你有一个可以接受 IIdentified
作为参数的方法,它应该能够接受所有类型的 IIdentified
而不仅仅是特定类型的 IIdentified
。你不能只给出一个可以处理 ProjectModel
的函数并假设它能够处理 IIdentified
.
的其他一些子类
如果我们改为将具有以下内容:
() => ProjectModel
那么这将是 () => IIdentified
的有效子类型,因为我们被允许 return 更具体的 IIdentified
。
我有实现 IIdentified
class 的 ProjectModel
class。但是在运行时,我得到一个错误,指出 ProjectModel
不是 IIdentified
的子类型,尽管它实现了它。我也曾尝试在 ProjectModel
中使用 extend
而不是 implements
但这也无济于事。我如何在 Dart Flutter 中使用接口,以便 Widget 可以具有满足特定接口或契约的通用类型?
Parent class IIdentified
我像接口一样使用:
abstract class IIdentified {
String id;
String name;
}
子 class 实现(也尝试扩展)父 class IIdentified
:
class ProjectModel implements IIdentified {
String id;
DateTime created;
DateTime updated;
bool hasMileage;
bool hasAllowance;
bool hasTravelTime;
String name;
String description;
DateTime startDate;
DateTime endDate;
DateTime completed;
double estimatedTime;
double absentTime;
double presentTime;
Status status;
String companyId;
String customerId;
ProjectModel(
{this.id,
this.created,
this.updated,
this.hasMileage,
this.hasAllowance,
this.hasTravelTime,
this.name,
this.description,
this.startDate,
this.endDate,
this.completed,
this.estimatedTime,
this.absentTime,
this.presentTime,
this.status,
this.companyId,
this.customerId});
我收到以下错误消息,我尝试传递的函数中的 ProjectModel
参数不算作 IIdentified
:
The following _TypeError was thrown building LoaderDropdownButton<ProjectModel>(dirty, dependencies: [MediaQuery], state: LoaderDropdownButtonState<IIdentified>#f2031):
type '(ProjectModel) => void' is not a subtype of type '(IIdentified) => void'
通用小部件只接受类型 T extends IIdentified
:
class LoaderDropdownButtonState<T extends IIdentified> extends State<LoaderDropdownButton<T>> {
double displayWidth;
double displayHeight;
@override
void initState() {
init();
super.initState();
}
@override
Widget build(BuildContext context) {
setDisplayDimensions();
return Container(
padding: EdgeInsets.only(left: 25),
color: widget.enableSelect ? themeConfig.dropButtonBg : themeConfig.dropButtonDisabledBg,
child: Theme(
data: ThemeData(canvasColor: Color(0xFFC5C5C5)),
child: DropdownButtonHideUnderline(
child: new DropdownButton<T>(
hint: Row(
children: <Widget>[
Expanded(
flex: 10,
child: Container(
alignment: Alignment.center,
margin: EdgeInsets.only(top: 2),
child: Text(
widget.text,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: widget.enableSelect
? themeConfig.dropButtonFg
: themeConfig.dropButtonDisabledFg,
fontSize: displayWidth * 0.045,
),
),
),
),
Flexible(
flex: 2,
child: Container(
margin: EdgeInsets.only(top: 5),
child: Icon(
Icons.keyboard_arrow_down,
color: widget.enableSelect
? themeConfig.dropButtonFg
: themeConfig.dropButtonDisabledFg,
),
),
)
],
),
iconSize: 0,
isExpanded: true,
items: buildItems(),
onChanged: widget.onChange),
),
),
);
}
void init() {
displayWidth = 1;
displayHeight = 1;
}
setDisplayDimensions() {
if (displayWidth == 1) displayWidth = MediaQuery.of(context).size.width;
if (displayHeight == 1) displayHeight = MediaQuery.of(context).size.height;
}
List<DropdownMenuItem<T>> buildItems() {
return widget.data.map((dataItem) {
return DropdownMenuItem<T>(
value: dataItem,
child: Text(dataItem.name),
);
}).toList();
}
}
为什么 ProjectModel
在 implements/extends 时不作为 IIdentified
通过?您如何在通用小部件中使用 interfaces/contracts?
谢谢!
I get the following error that the ProjectModel parameter in a function I'm trying to pass, does not count as being an IIdentified.
我不认为你真的粘贴了那个函数,但我仍然可以正确地猜到发生了什么。问题是您创建了一个带有签名的函数:
(ProjectModel) => void
并想将它用作需要 (IIdentified) => void
的参数。当我们谈论继承和方法参数时,这是一个常见的问题,因为它看起来有点落后。
但是,问题是如果你有一个可以接受 IIdentified
作为参数的方法,它应该能够接受所有类型的 IIdentified
而不仅仅是特定类型的 IIdentified
。你不能只给出一个可以处理 ProjectModel
的函数并假设它能够处理 IIdentified
.
如果我们改为将具有以下内容:
() => ProjectModel
那么这将是 () => IIdentified
的有效子类型,因为我们被允许 return 更具体的 IIdentified
。