【问题标题】:(OOP/Java) How should I handle this subclass-superclass relationship?(OOP/Java)我应该如何处理这种子类-超类关系?
【发布时间】:2013-09-20 19:32:59
【问题描述】:

我正在尝试制作棋盘游戏的移植版。棋盘游戏中的每个玩家选择八个不同角色中的一个。每个角色都有一个特殊的能力和一些风味文字,但除此之外,它们或多或少是相同的。

目前我有一个BaseHero 课程。我为八个不同的字符中的每一个创建了一个类,并让它们扩展BaseHero。但是,永远不会有同一个角色的多个实例。这是实现这一点的最佳方式吗?

我的替代想法是创建一个 CharacterList 类,其中将包含所有特殊能力的代码和布尔测试以确定它们是否存在于游戏中,但我觉得这太笨拙且明显不-模块化。

【问题讨论】:

  • 听起来很合理。我可能会在 BaseHero 中定义一些抽象方法,然后可以为每个特定英雄定义。
  • 你也可以为此创建一个枚举。

标签: java oop


【解决方案1】:

实例的数量与该类是否应该存在无关。一个类只实例化一次是完全正常的。您使用BaseHero 的设计听起来很合理。

【讨论】:

    【解决方案2】:

    我会将BaseHero 设为抽象,这样您就无法在不将其子类化为不同字符的情况下对其进行实例化,同时仍能获得一些不错的继承优势。您还可以强制使用单例模式,以便一次只能创建一个,但也可以很容易地设置一个标志来确定该字符是否被采用,就像您说的那样。

    CharacterList 应该是别的东西。如果你需要一个字符列表,你可以创建一个List<BaseHero>。将所有其他逻辑放入 List 类对我来说没有意义。

    此外,在制作角色时,请尝试遵循组合而非继承。例如,字符 HASA 能力而不是字符 ISA characterWithAbility。

    【讨论】:

    • 也许做一个 Set 而不是 List?这将有助于执行每种英雄规则的 1 个实例。
    【解决方案3】:

    我认为 BaseHero 应该是抽象类,并带有两个抽象方法 specialAbilitysomeFlavorText。您可以根据需要在角色自己的类中定义这两种方法。

    【讨论】:

      【解决方案4】:

      从我的角度来看,也许接口/抽象类是解决方案,例如:

      // the abstract interface which can be called "BaseHero"
      public interface Character {
      
          void action();
      
          void special();
      
          // another general methods
      
      }
      
      
      // The true implementation of the characters
      public class HeroOne implements Character{
      
          @Override
          public void action() {
              // do the actions
          }
      
          @Override
          public void special() {
              // do the specials
              HeroOneShapeAfterSpecial();
              // and so on
          }
      
          public void HeroOneShapeAfterSpecial(){
              // Hero One's special method
          }
      }
      
      
      // another implementation
      public class HeroTwo implements Character{
      
          @Override
          public void action() {
              // Hero Two action
          }
      
          @Override
          public void special() {
              // Hero Two Special
          }
      }
      
      
      
      //an example to use them
      public class Main {
      
          // a way to use those Characters
          public static void main(String[] args) {
              Character heroOne = new HeroOne();
              Character heroTwo = new HeroTwo();
      
              // some commands from what ever input
              heroOne.action();
              heroTwo.action();
              heroOne.action();
              heroTwo.special();
      
              //and so on
      
              // another way
              LinkedList<Character> charactersTeam = new LinkedList<Character>();
              charactersTeam.add(heroOne);
              charactersTeam.add(heroTwo);
      
              for(Character character : charactersTeam){
                  character.special();
              }
      
         }
      }
      

      一般来说,OO 设计偏向于组合而不是继承(HAS-A 关系比 IS-A 更好,更灵活)

      但是如果你想使用继承,你可以看看装饰器模式

      如果您希望子类不被多次实例化,您可以将您的子类设为 Singletons ... 像:

      Character heroOne = HeroOne.getInstance();
      Character heroTwo = HeroTwo.getInstance();
      

      对于你所说的特殊能力,special()方法可以绑定每个角色的特殊能力,因为它是抽象的,每个角色都会实现它

      【讨论】:

        【解决方案5】:

        我宁愿把它塑造成一个有文字和一些能力的英雄。文本来自属性文件。您可以先将常用文本加载到 Properties 对象中,然后再将特殊文本加载到 Properties 对象中。我会用不同的类别对每种能力进行建模。这允许您使用不同的能力集来模拟新的角色类。也许妖精有飞行和魔法,而飞马有飞行和速度左右。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-10-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多