如何在Dart子类构造函数中利用父类实例变量初始化final成员?
Dart子类构造函数中初始化final成员变量的问题解决
问题背景
在Java中,我们可以在子类构造函数中调用super()后,直接访问父类的实例变量来初始化子类的final成员:
Java父类代码
public class SqliteRepository { final MyDatabase db; public SqliteRepository(@NonNull Application application) { db = MyDatabase.get(application); } }
Java子类代码
public class CalculationRepository extends SqliteRepository { private final CalculationDao calculationDao; public CalculationRepository(@NonNull Application application) { super(application); calculationDao = db.calculationDao(); } }
尝试在Dart中实现相同逻辑时,编写了以下代码:
Dart父类代码
class SqliteRepository { final MyDatabase db; SqliteRepository({required BuildContext context}) : db = MyDatabase.instance; }
Dart子类代码
class CalculationRepository extends SqliteRepository { final CalculationDao _calculationDao; CalculationRepository({required super.context}) : _calculationDao = db.calculationDao; }
但出现报错:
The instance member 'db' can't be accessed in an initializer. Try replacing the reference to the instance member with a different expression
解决方案
Dart的初始化器列表执行时机早于父类构造完成后的实例成员可用时机,因此无法在初始化器中直接访问父类的db实例变量。可以通过以下两种方式解决:
方法1:使用late final延迟初始化
将子类的_calculationDao标记为late final,然后在构造函数体中完成赋值。构造函数体是在父类构造执行完成后才运行的,此时可以正常访问父类的db变量:
class CalculationRepository extends SqliteRepository { late final CalculationDao _calculationDao; CalculationRepository({required super.context}) { _calculationDao = db.calculationDao; } }
late关键字会保证变量在首次使用前完成初始化,同时保持final的不可变性。
方法2:复用父类的数据库获取逻辑
如果不想使用late,可以在父类中封装数据库的获取逻辑为静态方法,子类直接调用该静态方法来初始化_calculationDao:
修改后的父类代码
class SqliteRepository { final MyDatabase db; SqliteRepository({required BuildContext context}) : db = _getDatabase(); // 封装数据库获取逻辑为静态方法 static MyDatabase _getDatabase() { return MyDatabase.instance; } }
子类代码
class CalculationRepository extends SqliteRepository { final CalculationDao _calculationDao; CalculationRepository({required super.context}) : _calculationDao = SqliteRepository._getDatabase().calculationDao; }
这种方式避免了late的使用,同时保证了数据库获取逻辑的一致性,父类逻辑变更时子类无需单独修改。
内容的提问来源于stack exchange,提问作者Shahood ul Hassan
相关产品推荐
相关产品推荐

