如何组合2个派生自1个基类的2个方法?

时间:2016-04-24 10:25:22

标签: c# class inheritance abstract chess

我正在创造一个国际象棋游戏,我已经创建了车和主教,我即将开始制作女王棋子。问题是,女王结合了车的动作和主教的动作,所以我不想写重复的代码,而只是使用2个类为车和主教,他们是进入女王的方法。 / p>

这是主教班级

public class OficerPiece : Figure
{
    public OficerPiece(FigureDefinition definition) : base(definition)
    {
    }

    protected override List<Tuple<int, int>> GetValidTurns()
    {
        //here i set the valid moves
    }
}

车厢类基本相同,但GetValidTurns()

的实施方式不同

我项目中的每一个部分都继承了Figure抽象类,其中包含每个部分使用的唯一区别的信息在GetValidTurns方法中,因此我们将其留给派生类来实现。< / p>

那是女王级的

public class Kralica : Figure
{
    public Kralica(FigureDefinition definition) : base(definition)
    {
    }

    protected override List<Tuple<int, int>> GetValidTurns()
    {
        //here i want to combine the 2 methods GetValidTurns from the bishop class and the rook class
    }
}

3 个答案:

答案 0 :(得分:2)

你可能会以不同的方式来到这里。

有一个定义移动的抽象基类:

public abstract class Move
{
    // Whatever
}

然后从中得出不同的举动,例如:

public sealed class Diagonal : Move // Bishop, Queen
{
}

public sealed class Orthongonal : Move // Rook, Queen
{
}

public sealed class KnightsMove : Move
{
}

public sealed class KingsMove : Move
{
}

然后你可以使用合成来组合不同的动作:

public class Kralica : Figure
{
    public Kralica(FigureDefinition definition) : base(definition)
    {
    }

    protected override List<Move> GetValidTurns()
    {
        return moves;
    }

    readonly List<Move> moves = new List<Move> {new Diagonal(), new Orthongonal()};
}

您的Move类可能会声明如下:

public abstract class Move
{
    public abstract IEnumerable<Position> PossibleMoves(Position start, Board board);
}

其中Position是另一个定义为保存有关板上位置信息的类(可能只有X,Y坐标一样简单),而Board是一个保存有关位置信息的类所有的部分都在板上。

然后PossibleMoves()的实现将返回从给定位置开始并且电路板处于给定状态的该类型的所有可能移动的枚举。

答案 1 :(得分:1)

您可以为有效轮次创建新的类或接口,以封装它们并使其易于重用。

public interface ValidTurn
{
    List<Tuple<int, int>> GetValidTurns();
}

public class StraightSlide : ValidTurn
{
    public List<Tuple<int, int>> GetValidTurns()
    {
         // ... valid rook turns here
    }
}

public class DiagonalSlide : ValidTurn
{
    public List<Tuple<int, int>> GetValidTurns()
    {
         // ... valid bishops turns here
    }
}

public class Kralica : Figure
{
    public Kralica(FigureDefinition definition) : base(definition)
    {
    }

    protected override List<Tuple<int, int>> GetValidTurns()
    {
        var straight = new StraightSlide();
        var diagonal = new DiagonalSlide();

        return straight.Concat(diagonal);
    }
}

此外,原始类中的代码应替换为新的ValidTurn类。

修改

public class StraightSlide : ValidTurn
{
    private Figure figure;
    public StraightSlide(Figure figure)
    {
        this.figure = figure;
    }

    public List<Tuple<int, int>> GetValidTurns()
    {
         figure.YourMethodToCall();
         // ... valid rook turns here
    }
}

您可以考虑将所有验证逻辑放入ValidTurn(TurnValidation)。

答案 2 :(得分:0)

如果您是初学者,为什么不在您的基类中添加一些简单的方法?这会将移动添加到您的点列表中?

    public class Kralica : Figure
    {
        protected Tuple<int, int> Position {get; set;}

        public Kralica(FigureDefinition definition) : base(definition)
        {
        }

        protected override List<Tuple<int, int>> GetValidTurns()
        {
            //here i want to combine the 2 methods GetValidTurns from the bishop class and the rook class
        }

        protected void AddDiagonalMoves(List<Tuple<int, int>> moves)
        {
            diagonalMoves = new List<Tuple<int, int>>();

            // calculate diagonal moves from my piece position which should be a member property here

            moves.AddRange(diagonalMoves);
        }
    }


public class Kralica : Figure
{
    public Kralica(FigureDefinition definition) : base(definition)
    {
    }

    protected override List<Tuple<int, int>> GetValidTurns()
    {
        var movesThisTurn = new List<Tuple<int, int>>(); 
        //here i want to combine the 2 methods GetValidTurns from the bishop class and the rook class
        base.AddDiagonalMoves(movesThisTurn);
        base.AddLinearMoves(movesThisTurn);

    }
}

然后你的派生类可以在各自的GetValidTurns中重用这些方法来构建要返回的移动列表。

编辑:即使你是初学者,我也建议你在这里离开元组并创建一个简单的点#34;类或结构。它将使您的代码更具可读性,即使对您自己也是如此。