0

假设我有一个棋盘游戏,玩家可以在其中购买他们登陆的方块。我在 Squares 的抽象基类中有一个方法,称为:

public abstract void applyLandOnAffect(Player player);

然后在我的 BuyableSquares 类中,我实现了如下所示的方法:

@Override
 public void applyLandOnAffect(Player player){
    //Offer them the chance buy the square here.
}

然后,如果他们选择购买正方形,我希望对象从 BuyableSquares() 变为 BoughtSquare()。BoughtSquare 中的代码将处理当另一个玩家降落在购买的广场上时会发生什么。但问题是我应该如何以及在哪里改造它。

我在想这种类型的代码:

this = new BoughtSquare();

但它不是被接受的语法。

我该如何处理?

谢谢

4

6 回答 6

2

如果您使用多态性根据其类型对 Square 实例进行不同处理,我的建议是使用State design pattern

要在您的应用程序中引入它,您应该:

  • 定义一个名为 eg 的新接口SquareState,其方法因正方形类型而异

    public interface SquareState {
        void applyLandOnAffect(Player player);
    }
    
  • 定义将实现此接口并提供接口方法实现的所有方形SquareState类型

    public AvailableState implements SquareState {
        public void applyLandOnAffect(Player player) { // ..
        }
    }
    
    public BoughtState implements SquareState {
        public void applyLandOnAffect(Player player) { // ..
        }
    }
    
  • 在类中引入一个新属性,该属性Square将存储正方形的当前状态

    public class Square {
        private SquareState state;
        // ..
    }
    

一旦你这样做了,改变 Square 的状态将是一个调用的问题:

this.state = new BoughtSquare();
于 2013-05-21T23:35:10.300 回答
0

您应该只调用一个类,Square而不是为购买的方块和未购买的方块设置单独的类。Square或者,如果您计划拥有其他类型的不可购买的方块,您可以扩展。purchased在您的类中创建一个默认设置为的布尔值false。然后在购买正方形时,您可以将值设置为true

public class PurchaseableSquare extends Square
{
    private boolean purchased;

    public Square()
    {
        this.purchased = false;
    }

    public void purchaseSquare()
    {
        this.purchased = true;
    }
}
于 2013-05-21T23:37:34.630 回答
0

首先,您不能将任何内容分配给this.

为了实现你想要的,为什么不在BuyableSquares类中创建一个标志,指示该方块是否被购买。

 public class BuyableSquares extends Squares {

     private boolean bought = false; // by default

     //...

     public void markAsBought() {
          bought = true;
     }
 }
于 2013-05-21T23:37:47.647 回答
0

一旦你实例化了一个对象,你就不能改变它的类。

一个选项是,因为这两个类已经扩展了一个超类,所以将其用作对类的引用,以便您可以轻松地替换它们。因此,您将您的棋盘存储为 Square 的集合(或列表或数组),它们中的每一个都是 aBuyableSquare或 a BoughtSquare。当BuyableSquare必须转换 a 时,您可以用对应的结构替换它BoughtSquare(当然,建议BoughtSquare使用将原始结构BuyableSquare作为参数的构造函数)。

于 2013-05-21T23:39:07.450 回答
0

我同意上一篇文章的State模式是最好的。使用状态变量设置Square类,当该正方形发生不同事件时,您可以切换到不同状态。然后,让每个状态封装当玩家降落在广场上并且处于特定状态时发生的行为。要更改状态,只需将不同的实例重新分配SquareStatestate变量。一个非常简单的轮廓看起来像这样。

interface SquareState{
    void applyLandOnAffect(Player player);
}

public class Square{
  private SquareState state = new AvailabelState();
}

public AvailableState implements SquareState{
    public void applyLandOnAffect(Player player){
      ...
    }
}

public BoughtState implements SquareState{
    public void applyLandOnAffect(Player player){
      ...
    }
}
于 2013-05-21T23:40:40.893 回答
0

这是证明规则更喜欢组合而不是继承的示例之一。

在您的情况下,您有Square定义行为的子类型。问题是你的对象不能改变类,所以它不能从BuyableSquareto转换BoughtSquare。基于组合的设计将为广场的状态创建一个新界面。所以 Square 有一个SquareState. 购买和未购买方格的不同行为将在 SquareState 接口的不同子类型中定义。所以当有人购买一个方块时,你只需改变它的状态。就像是:

public class Square {
    private SquareState state = new Buyable();
    public void buyMe() {
        this.state=new Bought();
    }
}
于 2013-05-21T23:48:13.933 回答