【问题标题】:Base class function being called when child function should override当子函数应该覆盖时调用基类函数
【发布时间】:2018-04-29 17:52:16
【问题描述】:

我正在做一个国际象棋游戏并且有一个错误,子类中的覆盖方法并不总是覆盖父类。

更具体地说是 temp2.​​setgetMoves(generation),但仅在第二次用于作品时。发生错误是因为我在父类中使用了带有虚拟方法的继承,在子类中使用了覆盖方法。例如在父类中的方法是:

abstract class Piece
{
    String pieceType;
    int pieceVal;
    Panel piecePanel;


    public Piece(String type, int value, Panel image)
    {

        image.BackgroundImage = (Image)(Properties.Resources.ResourceManager.GetObject(type));

        pieceType = type;
        pieceVal = value;
        piecePanel = image;
    }

    public abstract List<Panel> setgetMoves(BoardGen board);

    public virtual List<Panel> getMoves()
    {
        return null;
    }

    public String getType()
    {
        return pieceType;
    }

    public void setPanel(Panel newPanel)
    {
        piecePanel = newPanel;
    }

    public Panel getPanel()
    {
        return piecePanel;
    }

    public int getValue()
    {
        return pieceVal;
    }
}

在子类中(例如,这是一个不完整的典当类,它还没有拿走棋子或过路人或促销,但这是我到目前为止所了解的全部)代码是:

class Pawn : Piece
{
    public List<Panel> possibleMoves;
    public Pawn(string type, int value, Panel image) : base(type, value, image)
    {

    }

    public override List<Panel> setgetMoves(BoardGen board)
    {
        possibleMoves = new List<Panel>();
        foreach (Panel x in board.getPanels())
        {
            if (this.getType().Substring(0, 1).Equals("W"))
            {
                if (this.getPanel().Location.Y == 240 && ((x.Location.Y == this.getPanel().Location.Y - 40) || (x.Location.Y == this.getPanel().Location.Y - 80)) && (x.Location.X == this.getPanel().Location.X))
                {
                    possibleMoves.Add(x);
                }

                else if((x.Location.Y == (this.getPanel().Location.Y - 40)) && (x.Location.X == this.getPanel().Location.X))
                {

                    possibleMoves.Add(x);
                }
            }
            else if (this.getType().Substring(0,1).Equals("B"))
            {
                if (this.getPanel().Location.Y == 40 && ((x.Location.Y == this.getPanel().Location.Y + 40) || (x.Location.Y == this.getPanel().Location.Y + 80)) && (x.Location.X == this.getPanel().Location.X))
                {
                    possibleMoves.Add(x);
                }
                else if (x.Location.Y == this.getPanel().Location.Y + 40 && (x.Location.X == this.getPanel().Location.X))
                {
                    possibleMoves.Add(x);
                }
            }
        }
        return possibleMoves;
    }

    public override List<Panel> getMoves()
    {
        return possibleMoves;
    }

任何关于为什么它可能不会第二次覆盖的帮助都会非常有帮助。谢谢。

【问题讨论】:

  • 我不知道为什么这与一个不相关的问题重复链接。我猜 Plutonix、Camilio 和 Uwe 没有读过这个问题?您提供的代码不足以指出错误;也许您可以将基类和 setgetMoves-method 抽象化,然后查看是否出现编译器错误。只是一个建议,不能保证它有助于找到错误。
  • 感谢您的回复。加入抽象基类abstract后,代码编译前出现错误。它说我可能不会创建抽象类“Piece”的实例。知道如何解决这个问题吗?
  • 啊,我刚刚正确阅读了您对Piece temp3 = new Piece(temp2.getType(), temp2.getValue(), panel); 的评论,这就是问题所在,您没有创建正确类型的对象。 EventHorizo​​n 提到 Activator 是对“当在字符串中找到对象类型的名称时创建对象”这一一般问题的回答,但我希望您后退一步,重新思考您为什么要这样做.
  • 在国际象棋中,只能在两次创建棋子:第一次设置棋盘时,以及当棋子到达远端并被提升时(通常是皇后,但车,马,主教也是可能的,有时是必要的,以防止平局)。在所有其他时间,棋子会被移动或销毁(捕获),但移动不会产生新的棋子。
  • 所以我编辑了所有内容,我现在正在更新面板而不是创建新的部分,它运行良好。谢谢!!

标签: c# inheritance nullreferenceexception chess


【解决方案1】:

由于来回的 cmets 发现了一个可能的 X-Y 问题,我想帮助修复您的 setPanel() 函数。希望这允许您重用正确类型的现有对象,并避免创建没有正确类型的全新对象(因此找不到正确的覆盖)。

您的构造函数对其 Panel 参数的 BackgroundImage 属性进行了更改:

image.BackgroundImage = (Image)(Properties.Resources.ResourceManager.GetObject(type));

因此,当我们更改面板时,我们应该撤消之前与原面板的交互,并为新面板重做:

public void setPanel(Panel newPanel)
{
    newPanel.BackgroundImage = piecePanel.BackgroundImage;
    piecePanel.BackgroundImage = null;
    piecePanel = newPanel;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-16
    • 1970-01-01
    • 2010-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多