Dart继承ChangeNotifier父类操作子类自有数据的实现方案
问题原因
Dart中以下划线开头的成员为库级私有成员,当前实现的核心问题有两个:
- 父类中定义的
_map和子类中自定义的_people、_groups是完全独立的三个变量,父类封装的add/remove方法只能访问自身持有的_map,根本无法操作子类中定义的私有存储集合 - 子类继承泛型父类时没有传入明确的泛型参数,类型约束完全失效,也无法让父类的存储集合自动适配子类需要存储的数据类型
修复方案
不需要在子类中重复定义存储集合,子类继承父类时直接传入明确的泛型参数即可,父类会自动为每个子类实例生成独立的、类型匹配的存储集合,既可以复用父类的通用增删改查逻辑,又能实现不同子类的数据隔离。
修复后代码
1. 父类 object_list_provider.dart
补全参数类型约束,保留统一的通用操作逻辑:
import 'package:flutter/material.dart'; class ObjectListProvider<T extends num, K extends Object> with ChangeNotifier { final Map<T, K> _map = {}; Map<T, K> get map => {..._map}; K? getSingleObjectWithId(T id) => _map[id]; void add(T id, K obj) { _map[id] = obj; notifyListeners(); } void remove(T id) { _map.remove(id); notifyListeners(); } void clear() { _map.clear(); notifyListeners(); } }
2. 人员列表子类 person_list.dart
指定泛型参数,不需要重复定义存储集合,可直接扩展人员模块专属业务方法:
import 'object_list_provider.dart'; import '../person.dart'; class PersonList extends ObjectListProvider<int, Person> { // 可在此处编写Person模块独有的业务逻辑 }
3. 分组列表子类 group_list.dart
指定泛型参数,修正原有错误的人员添加逻辑,基于父类的通用查询方法扩展分组专属操作:
import './object_list_provider.dart'; import '../group.dart'; import '../person.dart'; class GroupList extends ObjectListProvider<int, Group> { void addPersonToGroup(Person person, int groupId) { final targetGroup = getSingleObjectWithId(groupId); if (targetGroup == null) return; targetGroup.addPerson(person); notifyListeners(); } void removePersonFromGroup(int personId, int groupId) { final targetGroup = getSingleObjectWithId(groupId); if (targetGroup == null) return; targetGroup.removePerson(personId); notifyListeners(); } }
Group和Person实体类不需要修改,保持原有实现即可。
使用方式
原有调用逻辑完全兼容,不同Provider实例的数据完全隔离:
// 操作分组列表 final groupList = Provider.of<GroupList>(context); groupList.add(1, Group(id: 1, name: "周末聚餐")); // 操作人员列表,和分组列表数据完全独立 final personList = Provider.of<PersonList>(context); personList.add(1, Person(id: 1, name: "张三"));
实现效果
- 每个子类实例持有独立的存储集合,不同模块数据完全隔离,不会互相污染
- 通用增删查逻辑全部在父类封装,子类无需重复编写重复代码
- 所有操作执行完成后自动触发状态通知,UI层可自动同步刷新
- 泛型约束全程生效,数据操作时会自动做类型检查,避免类型错误
内容的提问来源于stack exchange,提问作者mert Özerdem
相关产品推荐
相关产品推荐

