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
相关产品推荐
相关产品推荐

