【问题标题】:What should be included in an abstract class? [closed]抽象类中应该包含什么? [关闭]
【发布时间】:2016-06-23 08:37:44
【问题描述】:

我正在完成一个战舰项目。但一切都在一个类中。我想让它更面向对象。

建议我应该使用:Cell(Abstract 类),然后使用 Water、Misses、ShipSection 作为子类。我应该在 Cell 抽象类中包含什么?什么样的方法,构造函数。以及如何在“水”类中使用它们?

谢谢

【问题讨论】:

  • 您通常从描述您的问题域开始,然后从那里您继续开发适合您的问题域的域对象模型(定义了所有关系)。如果你最终得到了一个包含所有内容的类,那么你已经做错了。

标签: java inheritance polymorphism abstract-class


【解决方案1】:

Cell 类应该包含所有后代的通用功能,并让他们实现差异。让我们找出什么是不同的,什么是共同的。

常见:

  • 必须能够绘制所有单元格
  • 所有细胞都必须能够被击中
  • 所有细胞都有状态:是否被击中。

不同:

  • 每个单元实现都有自己的绘制方法,具体取决于其状态。
  • 每个单元实现都有自己的罢工反应:是未命中还是命中。

在实施过程中,您可以找到其他常见和不同功能的示例。

顺便说一句,如果我们分析它,结果表明细胞应该根据它的状态(被击中与否)来绘制自己。因为Miss 是一个受灾的Water 单元,所以你根本不需要单独的Miss 类。怀念刚刚遇水的状态。

因此,您的 Cell 类可能如下所示:

public abstract class Cell{

   private boolean isStricken = false;

   public void draw(){
       if(isStricken){
           drawStricken();
       }else{
           drawNotStricken();
       }
   }

   public boolen strike(){
       isStricken = true;
       return isItHit();
   }

   protected abstract void drawNotStricken();
   protected abstract void drawStricken();
   protected abstract boolean isItHit();
}

ShipSection 只会实现差异:

public class ShipSection extends Cell{
    @Override
    protected void drawNotStricken(){
        //draw section
    }

    @Override     
    protected void drawStricken(){
        //draw section in fire
    }

    @Override
    protected boolean isItHit(){
        return true
    }
}

同样的方式你可以实现Water 类(正如你猜到的,水会在isItHit() 方法中返回false)。现在,例如,如果你有一个类BattleField,它包含所有单元格并将它们存储在数组中,接下来可以使用:

public class BattleField{

    Cell[][] cellArray = new Cell[rowCount][colCount] ;

    ....

    public void draw(){
        for(Cell[]row : cellArray){
            for(Cell cell : row){
                cell.draw();
            }
        }
    }

    public boolean strike(int row, int col){
        Cell cell = cellArray[row][col];
        return cell.strike();
    }
}

这段代码是简化的,只是为了演示一般的想法。如您所见,我们的BattleField 类对单元的实现一无所知,并将所有单元用作抽象Cell

请记住,这只是类层次结构设计的示例,根据要求您可以自己制作,与此不同。希望这会有所帮助。

【讨论】:

    【解决方案2】:

    对于字段,请考虑每个类的共同点。如果您扩展抽象类,请确保调用super。对于抽象方法,请考虑每个子类中必需的方法。并使构造函数初始化字段。我提供的例子很简单。如果有的话,我还会为你的抽象类中的字段添加“get”方法。

    public class Water extends Cell
    {
      public Water(/*parameters*/)
      {
        super(/*parameters*/);
      }
    
      @Override
      public void speak()
      {
        System.out.print("I am water.");
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2012-05-26
      • 2022-01-02
      • 2011-08-18
      • 1970-01-01
      • 2022-10-07
      • 2015-09-13
      • 1970-01-01
      • 2010-10-19
      • 1970-01-01
      相关资源
      最近更新 更多