Flutter中如何强制参数与对象为相同静态具体类型?
解决方案:泛型约束的抽象基类
可以通过给抽象基类Vehicle添加递归泛型约束,在编译阶段强制setInDB方法只能接受与当前实例同类型的参数,同时保留基类的通用实现,避免代码重复。
实现代码
abstract class Vehicle<T extends Vehicle<T>> { // 假设dbLocation是每个子类都需实现的数据库路径属性 String get dbLocation; // 基类统一实现数据库写入逻辑 Future<void> setInDB(T updated) => database.set(dbLocation, updated); } class Car extends Vehicle<Car> { @override final String dbLocation = 'cars/xxx'; // 子类无需重写setInDB,直接继承基类通用逻辑 } class Truck extends Vehicle<Truck> { @override final String dbLocation = 'trucks/yyy'; }
方案优势
编译时类型安全:
- 调用
car.setInDB(anotherCar)时,若传入非Car类型(如Truck),编译器直接报错,无需依赖运行时检查。 - 即使变量静态类型为
Vehicle<Car>,调用setInDB也只能传入Car类型,彻底杜绝跨类型更新。
- 调用
消除代码重复:
- 所有子类的数据库写入逻辑统一在基类实现,子类仅需实现自身特有的属性(如
dbLocation),无需重复编写相同代码。
- 所有子类的数据库写入逻辑统一在基类实现,子类仅需实现自身特有的属性(如
强制子类规范:
- 新增子类时必须指定自身作为泛型参数(如
class Motorcycle extends Vehicle<Motorcycle>),否则基类setInDB方法无法正常使用,从根源避免“忘记重写方法”的问题。
- 新增子类时必须指定自身作为泛型参数(如
对比原有方案的改进
- 对比方案1:无需依赖
covariant关键字,也不需要子类重写setInDB,静态类型场景下也能保证类型安全,彻底摆脱运行时检查依赖。 - 对比方案2:完全消除子类间的代码重复,通用逻辑集中在基类,维护成本更低。
内容的提问来源于stack exchange,提问作者Anakhand
相关产品推荐
相关产品推荐

