You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 04:01:18