[英]How to call different class factory fromJson constructors via a variable in a parent (abstract) class method
I have an abstract class Listicle
with a method, fetchItem()
that includes我有一个抽象类
Listicle
,它的方法fetchItem()
包括
var item = Stock.fromJson(itemMap);
But I want to be able to use this method in various child classes, say in addition to StockListicle
also in ClientListicle
etc.但我希望能够在各种子类中使用这种方法,比如除了
StockListicle
之外,还在ClientListicle
等中。
I imagined it should be possible to do something like pass a type parameter to the parent class' method, but how?我想应该可以做一些事情,比如将类型参数传递给父类的方法,但是怎么做呢?
I've tried things like:我试过这样的事情:
Future<Item> fetchItem(Type theType) async {
//...
Map<String, dynamic> itemMap = jsonDecode(response.body);
var item = theType.fromJson(itemMap);
//...
But get the error但是得到错误
The method 'fromJson' isn't defined for the type 'Type' - maybe its just a syntax thing?
方法 'fromJson' 没有为类型 'Type' 定义 - 也许它只是一个语法问题?
In my case Stock
extends Item
, and Stock has a fromJson factory constructor,在我的例子中,
Stock
扩展了Item
,并且 Stock 有一个 fromJson 工厂构造函数,
class Stock extends Item {
final String thumbUrl;
const Stock(
{required super.id,
required super.title,
required super.description,
required this.thumbUrl});
@override
List<Object> get props => [id, title, description, thumbUrl];
factory Stock.fromJson(Map<String, dynamic> json) {
developer.log('Stock.fromJson:');
return Stock(
id: json['id'],
title: json['title'],
description: json['description'],
thumbUrl: json['thumbUrl'],
);
}
}
abstract class Item extends Equatable {
const Item({
required this.id,
required this.title,
required this.description,
});
final int id;
final String title;
final String description;
@override
List<Object> get props => [id, title, description];
}
I've also tried declaring an abstract method in the parent class containing the method in question to try and have that set by its child class, but no luck:我还尝试在包含相关方法的父类中声明一个抽象方法,以尝试由其子类设置该方法,但没有运气:
in the abstract class Listicle extends ChangeNotifier {...
在
abstract class Listicle extends ChangeNotifier {...
Type getType();
in then in the the child class StockListicle extends Listicle {
然后在子
class StockListicle extends Listicle {
@override
Type getType() {
return (Stock);
}
Another throught was to connect the necessary functionality, so in the parent/base listicle `Function fromJsonFactory(json);'另一个方法是连接必要的功能,因此在父/基础列表中 `Function fromJsonFactory(json);' and then in the StockListicle something like
然后在 StockListicle 中类似
@override
Function fromJsonFactory(json){
return Stock.fromJson;
}
and和
var item = fromJsonFactory(itemMap) ;
but that gives但这给了
A value of type 'Function' can't be returned from the method 'fetchItem' because it has a return type of 'Future'.
无法从方法“fetchItem”返回“Function”类型的值,因为它的返回类型为“Future”。
Or is this 'counter-pattern' and I should just duplcate and amend the method between the child classes - it would seem awfully redundant though.或者这是“反模式”,我应该只是复制和修改子类之间的方法——尽管它看起来非常多余。
Thanks in advance.提前致谢。
I'm sure there must be a better way, however I got it working with an old-school switch:我确信一定有更好的方法,但是我用老式开关让它工作:
Future<Item> fetchItem(Type theType) async {
//...
switch (theType) {
case Stock:
return Stock.fromJson(itemMap);
case Client:
return Client.fromJson(itemMap);
default:
throw Exception("Didn't recognize $theType item type.");
}
and in the child class I call在我打电话的孩子班里
Stock tmpStock = await fetchItem(Stock) as Stock;
So, it seems the Type type is more like just a string version of the class name - though sure there must be something more elegant though at least this is quite readable ¯_(ツ)_/¯.因此,Type 类型似乎更像是类名的字符串版本——尽管肯定有一些更优雅的东西,尽管至少这是相当可读的¯_(ツ)_/¯。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.