【问题标题】:Accessing object from another class of the same parent从同一个父类的另一个类访问对象
【发布时间】:2021-12-27 17:30:58
【问题描述】:

我正在将之前在 JAVA 上编写的面向对象的代码转移到 dart 中,以便通过 Flutter 框架在我的设备上对其进行可视化测试。
我有一个名为 Person 的类,它有两个子类 SuperPerson(有两个子类 SuperHero >Villian 并且有 Attack 方法)和 Civil。我为 SuperHero 类创建了一个名为 protect 的方法,旨在保护对象免受 Civil 类的侵害。

现在,当 VillianSuperHero 上多次调用 Attack 方法时,我正试图做到这一点对象的生命值达到零,这使得 SuperHero 对象不再保护 Civil。而且我不太确定如何访问 Civil 的对象,以便在死后使它们不受 SuperHero 对象的保护。

人员类

class Person {
 //civil side
   String protector = '';
   bool protection = false;
  //hero side
   String protectedTargetName = '';
   bool protecting = false;

  //setters
    //Civil side
      String setProtector(String protector) {
        return this.protector = protector;
      }
    
      bool setCivilProtection(bool protection) {
        return this.protection = protection;
      }
    
    //Hero Side
      String setProtectedTargetName(String protectedTargetName) {
        return this.protectedTargetName = protectedTargetName;
      }
    
      bool setHeroProtection(bool protecting) {
        return this.protecting = protecting;
      }

    //getters
    //civil side
      String getProtector() {
        return protector;
      }
    
      bool isProtected() {
        return protection;
      }
    
    //hero side
      String getProtectedTargetName() {
        return protectedTargetName;
      }
    
      bool isProtecting() {
        return protecting;
      }
  }

超级英雄类

class SuperHero extends SuperPerson
{      
  SuperHero(String n, int a, String s, String p) : super(n, a, s, p) {
        setProtectedTargetName('none');
        setHeroProtection(false);
      }

 void toProtect(Person target, BuildContext context) {
    String tName = target.getName();
    String pName = getName();
    setProtectedTargetName(target.getName());//Hero's side
    setHeroProtection(true);//Hero's side
    target.setCivilProtection(true);//Civil's side
    target.setProtector(getName());//Civil's side
    final snackBar = SnackBar(
      duration: const Duration(milliseconds: 500),
      content: Text('$tName is under $pName\'s protection.'),
    );
    ScaffoldMessenger.of(context).showSnackBar(snackBar);
  }

  void toUnProtect(Person target, BuildContext context) {
    String tName = target.getName();
    String pName = getName();
    setProtectedTargetName('none');//Hero's side
    setHeroProtection(false);//Hero's side
    target.setCivilProtection(false);//Civil's side
    target.setProtector('none');//Civil's side
    final snackBar = SnackBar(
      duration: const Duration(milliseconds: 500),
      content: Text('$tName is no longer under $pName\'s protection'),
    );
    ScaffoldMessenger.of(context).showSnackBar(snackBar);
  }
}

民事类

class Civil extends Person {
  //Constructor
  Civil(String n, int a, String s) : super(n, a, s) {
    setProtector('None');
    setCivilProtection(false);
  }
}

Villian Class:这里只移除SuperHero方面的保护,但Civil方面仍有保护我不知道如何从这里访问它。

void attack(Person target, BuildContext context) {
    String tName = target.getName();
    String tPronouns = target.pronouns();
    String tProtector = target.getProtectorName();
    if (!(target.isProtected())) {
      super.attack(target, context);
      if (target.isProtecting()) {
        if (target.getHealth() == 0) {
          final snackBar = SnackBar(
            duration: const Duration(milliseconds: 500),
            content:
                Text('$tName is no longer under $tProtector\'s protection'),
          );
          ScaffoldMessenger.of(context).showSnackBar(snackBar);
          //Hero side
          target.setProtectedName('none');
          target.setHeroProtection(false);
          //Supposed to be Civil side but idk how to do it properly
          setCivilProtection(false);
          setProtectorName('none');
        }
      }
    } else {
      final snackBar = SnackBar(
        duration: const Duration(milliseconds: 500),
        content: Text(
            'You can\'t attack $tName, $tPronouns is already under $tProtector\'s protection'),
      );
      ScaffoldMessenger.of(context).showSnackBar(snackBar);
    }
  }

更新
在 Java 中声明一个负责存储受保护 Civil 的变量可以正常工作且没有错误。但是,当我尝试将其转移到 dart 时,我收到了一个错误,因为我对 dart 不太熟悉。
人物类

Person protectedPerson; //Error at this line

  Person getProtectedPerson() {
    return protectedPerson;
  }

  Person setProtectedPerson(Person protectedPerson) {
    return this.protectedPerson = protectedPerson;
  }

错误:

    Non-nullable instance field 'protectedPerson' must be initialized.
Try adding an initializer expression, or add a field initializer in this constructor, or mark it 'late'.

当我试图解除对Civil的保护时,除了收到另一个错误之外。 不知道有没有其他方法可以让这个函数接受 Null 值。

setProtectedPerson(null);

错误:

The argument type 'Null' can't be assigned to the parameter type 'Person'.

更新 - 解决方案

在类型后添加问号有助于解决所有错误。

Person? protectedPerson;

  Person? getProtectedPerson() {
    return protectedPerson;
  }

  Person? setProtectedPerson(Person? protectedPerson) {
    return this.protectedPerson = protectedPerson;
  }`

【问题讨论】:

    标签: java class dart object oop


    【解决方案1】:

    一个超级英雄可以保护多个平民吗?如果是这样,请将 SuperHero 当前正在保护的 Civils 列表 (List<Civil>) 存储为属性。每当超级英雄死亡时,移除对应超级英雄列表中所有成员的保护者。

    List<Civil> protectedCivils;
    
    // Whenever you want to remove all of the SuperHero's (target) protection of its Civils.
    target.removeProtectedCivils();
    
    // What the method would look like
    void removeProtectedCivils() {
       for(Civil civil : protectedCivils) civil.removeProtection();
    }
    

    否则,如果SuperHero只能保护一个Civil,则将当前受保护的Civil作为一个属性存储在SuperHero中,然后您可以在需要删除保护关系时随时访问它。总体而言,您的代码外观可以通过仅引用相关对象而不是使用字符串和布尔值来改进。

    【讨论】:

    • 当我创建变量来存储受保护的 Civil 以便 SuperHero 可以访问时,它在 JAVA 中运行良好。但是,当我尝试将其转移到 dart 时,我收到了几个我不知道如何修复它们的错误。您可以查看我编辑的帖子以获得进一步的说明。
    • @maghraby 对不起,我从来没有接触过 Dart,所以我无法帮助你,但我很确定必须有一种方法可以在 Dart 中存储对自定义类的引用,而不是使用字符串。
    • 我刚刚想出了如何解决这些错误。还是谢谢你。
    猜你喜欢
    • 2013-09-23
    • 2021-08-06
    • 1970-01-01
    • 1970-01-01
    • 2011-04-18
    • 1970-01-01
    • 2018-08-20
    • 1970-01-01
    • 2022-11-01
    相关资源
    最近更新 更多