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

Flutter技术问题:如何调用结构相似类中的数据?

解决随机选择类调用同名方法的问题(附代码重构优化)

要实现随机选择apple或pear类并调用同名方法,最佳实践是通过抽象基类定义统一接口,让两个类实现该接口,再通过随机选择实例来调用方法。同时解决原代码中全局变量冲突、重复代码过多的问题。

一、核心问题修正

  • 全局变量冲突:原代码中randomminmax1/2/3是全局变量,调用不同类的方法时会互相覆盖数据,必须移到类内部作为实例变量。
  • 重复代码冗余:两个类的giveQuestion和giveAnswer逻辑几乎一致,仅水果名称不同,可通过抽象基类提取公共逻辑。
  • 类型不安全:直接存储类的列表无法保证类型,通过抽象接口约束,确保所有类都有指定方法。

二、实现步骤

1. 定义抽象基类

创建抽象类FruitExercise,统一方法接口并提取公共逻辑:

abstract class FruitExercise {
  late int randomminmax1;
  late int randomminmax2;
  late int randomminmax3;
  final String fruitName;

  FruitExercise(this.fruitName);

  String giveQuestion() {
    randomminmax1 = 2 + Random().nextInt(15 - 2);
    randomminmax2 = randomminmax1 * (2 + Random().nextInt(12 - 2));
    randomminmax3 = 2 + Random().nextInt(30 - 2);

    List<String> value_1 = [" boxes", " bags", " bucket"];
    List<String> verbs = ["cost", "have a price of", "are offered for"];
    List<String> value_2 = ["Euro"];

    int randomIndexValue1 = Random().nextInt(value_1.length);
    int randomIndexVerbs = Random().nextInt(verbs.length);
    int randomIndexValue2 = Random().nextInt(value_2.length);
    
    String value = "${randomminmax1}${value_1[randomIndexValue1]} $fruitName ${verbs[randomIndexVerbs]} ${randomminmax2} ${value_2[randomIndexValue2]}.\n";
    String question = "How much are ${randomminmax3}${value_1[randomIndexValue1]}?\n";
    return value + question;
  }

  String giveAnswer() {
    double result = (randomminmax2 / randomminmax1) * randomminmax3;
    return "${result.toStringAsFixed(2)} Euro.";
  }
}

2. 实现具体水果类

让Apple和Pear继承抽象基类,仅需传入水果名称:

class Apple extends FruitExercise {
  Apple() : super("apples");
}

class Pear extends FruitExercise {
  Pear() : super("pears");
}

3. 实现随机选择类OverClass

修改OverClass,随机创建具体类的实例并返回,直接调用统一接口方法:

class OverClass {
  static final Random _random = Random();
  static final List<FruitExercise Function()> _fruitFactories = [
    () => Apple(),
    () => Pear(),
  ];

  static FruitExercise pickRandomFruit() {
    int index = _random.nextInt(_fruitFactories.length);
    return _fruitFactories[index]();
  }
}

4. 使用示例

void main() {
  // 随机选择一个水果习题类
  FruitExercise exercise = OverClass.pickRandomFruit();
  
  // 生成习题和答案
  print("习题:\n${exercise.giveQuestion()}");
  print("答案:\n${exercise.giveAnswer()}");
}

三、完整优化代码

import 'dart:math';

abstract class FruitExercise {
  late int randomminmax1;
  late int randomminmax2;
  late int randomminmax3;
  final String fruitName;

  FruitExercise(this.fruitName);

  String giveQuestion() {
    randomminmax1 = 2 + Random().nextInt(15 - 2);
    randomminmax2 = randomminmax1 * (2 + Random().nextInt(12 - 2));
    randomminmax3 = 2 + Random().nextInt(30 - 2);

    List<String> value_1 = [" boxes", " bags", " bucket"];
    List<String> verbs = ["cost", "have a price of", "are offered for"];
    List<String> value_2 = ["Euro"];

    int randomIndexValue1 = Random().nextInt(value_1.length);
    int randomIndexVerbs = Random().nextInt(verbs.length);
    int randomIndexValue2 = Random().nextInt(value_2.length);
    
    String value = "${randomminmax1}${value_1[randomIndexValue1]} $fruitName ${verbs[randomIndexVerbs]} ${randomminmax2} ${value_2[randomIndexValue2]}.\n";
    String question = "How much are ${randomminmax3}${value_1[randomIndexValue1]}?\n";
    return value + question;
  }

  String giveAnswer() {
    double result = (randomminmax2 / randomminmax1) * randomminmax3;
    return "${result.toStringAsFixed(2)} Euro.";
  }
}

class Apple extends FruitExercise {
  Apple() : super("apples");
}

class Pear extends FruitExercise {
  Pear() : super("pears");
}

class OverClass {
  static final Random _random = Random();
  static final List<FruitExercise Function()> _fruitFactories = [
    () => Apple(),
    () => Pear(),
  ];

  static FruitExercise pickRandomFruit() {
    int index = _random.nextInt(_fruitFactories.length);
    return _fruitFactories[index]();
  }
}

void main() {
  FruitExercise exercise = OverClass.pickRandomFruit();
  print("习题:\n${exercise.giveQuestion()}");
  print("答案:\n${exercise.giveAnswer()}");
}

四、关键改进说明

  • 抽象接口约束:确保所有水果类都实现指定方法,避免类型错误
  • 实例变量替代全局变量:每个水果实例拥有独立计算变量,不会互相干扰
  • 代码复用:抽象基类提取公共逻辑,新增水果类只需传入名称即可
  • 优雅的随机实例生成:通过工厂函数列表创建实例,比直接存储类更灵活

内容的提问来源于stack exchange,提问作者HolyPoly

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 12:18:27