![](/img/trans.png)
[英]calling an abstract method in a concrete method inside an abstract class in C#
[英]C#: Calling an abstract class method which is implemented through another abstract class
我正在用C#創建紙牌游戲。
我有一個抽象類“ Card”:
public abstract class Card
{
}
僅用於提供普通父母(即:公爵是卡,船長也是卡)
以下抽象子類繼承自Card,並用於進一步指定Card的類型(即:Assasin是targetCard,duke是moneycard),每個抽象子類都包含一個名為“ Action”的抽象方法,該抽象方法具有與自身相關的參數: MoneyCard具有抽象方法,該抽象方法將Player和ChipStack作為參數,TargetCard具有抽象方法,將Player和TargetPlayer等作為輸入。
public abstract class PassiveCard : Card
{
public abstract void Action();
}
public abstract class DeckInteractionCard : Card
{
public abstract void Action(Player player, Deck deck);
}
public abstract class MoneyCard : Card
{
public abstract void Action(Player player, ChipStack chipStack);
}
public abstract class TargetCard : Card
{
public abstract void Action(Player player, Player targetPlayer);
}
之后,我將對每種類型的卡進行具體的實現。 它們每個都繼承自上面提到的與自己相關的抽象類之一。
當然,每張卡還完全實現了從其父Abstract-class獲得的abstract方法。
class Duke : MoneyCard
{
public override void Action(Player player, ChipStack chipStack)
{
for (int i = 0; i < 3; i++)
{
player.TakeChip(chipStack);
}
}
public override string ToString()
{
return "Duke";
}
}
class Captain : TargetCard
{
//this card gives passive protection: how do we do this
public override void Action(Player player, Player targetPlayer)
{
if (targetPlayer.PlayerChips.Count >= 2)
{
targetPlayer.GiveChip(2, player);
}
}
public override string ToString()
{
return "Captain";
}
}
class Contessa : PassiveCard
{
//this card gives passive protection: how do we do this:
//give the receiving player the option to bluff, show that he really has a contessa, or deny the other having an assasin
public override void Action()
{
throw new NotImplementedException();
}
public override string ToString()
{
return "Contessa";
}
}
class Ambassador : DeckInteractionCard
{
//this card gives passive protection: how do we do this
public override void Action(Player player, Deck deck)
{
//open dialog: which 2 cards would you like to keep?
//(now, this action just doubles the players hand)
for (int i = 0; i < 2; i++)
{
player.PlayerHand.HandContent.Add(deck.DrawCard());
}
}
public override string ToString()
{
return "Ambassador";
}
}
class Assassin : TargetCard
{
public override void Action(Player player, Player targetPlayer)
{
if (player.PlayerChips.Count >= 3 && targetPlayer.FoldedAllCards == false)
{
for (int i = 0; i < 3; i++)
{
player.PlayerChips.RemoveAt(player.PlayerChips.Count - 1);
}
targetPlayer.FoldCard();
}
}
public override string ToString()
{
return "Assassin";
}
}
現在針對我的實際問題:
我有一個Player課。 我要在播放器類中創建一個方法,該方法將通用的“紙牌”作為輸入,然后調用與該特定類型的“紙牌”相關的操作方法卡。 像這樣:
public void CardAction(Card card)
{
card.Action();
}
上面的示例不起作用:編譯器抱怨Abstract類Card沒有稱為action的方法(這很有意義)
因此:我將如何創建一個將通用Card作為輸入並調用與我們作為輸入提供的SPECIFIC卡相關的SPECIFIC Action()方法的方法?
提前致謝,
羅伯特
我認為您的Action
方法過於籠統,但是您可以使其起作用。
而不是對Action
進行多個簽名,而只使一個僅接收一個參數Context
簽名。 在此參數中,放入操作的不同實現可能需要的所有內容。 這是示例:
public class Context
{
public Player Player;
public Player TargetPlayer;
public ChipStack ChipStack;
...
}
public abstract class Card
{
public abstract void Action(Context c);
}
...
public class Duke : MoneyCard
{
public override void Action(Context c)
{
for (int i = 0; i < 3; i++)
{
c.Player.TakeChip(c.ChipStack);
}
}
public override string ToString()
{
return "Duke";
}
}
public void CardAction(Card card)
{
var c = new Context { Player = p1, TargetPlayer = p2, ChipStack = chips };
card.Action(c);
}
我在這里看到兩個解決方案:您可以檢查每種卡的類型,然后調用適當的方法:
var pCard = card as PassiveCard;
if(pCard != null)
{
pCard.Action();
return;
}
var diCard = card as DeckInteractionCard;
if(diCard != null)
{
diCard.Action(player, deck);
return;
}
var mCard = card as MoneyCard;
if(mCard != null)
{
diCard.Action(player, chipStack);
return;
}
var tCard = card as TargetCard;
if(tCard != null)
{
tCard.Action(player, targetPlayer);
return;
}
或者,您可以為Card
類提供一個包含所有可能參數的抽象方法:
public abstract class Card
{
public abstract void Action(Player player, Player targetPlayer, Deck deck, ChipStack chipStack);
}
然后只需實現此方法,並忽略不必要的參數即可。 或者,如果您不希望此方法可見(僅顯示具有必需參數的方法),則可以使基類成為接口並進行顯式實現。
public abstract class PassiveCard : Card
{
public abstract void Action();
public override void Action(Player player, Player targetPlayer, Deck deck, ChipStack chipStack)
{
Action();
}
}
public abstract class DeckInteractionCard : Card
{
public abstract void Action(Player player, Deck deck);
public override void Action(Player player, Player targetPlayer, Deck deck, ChipStack chipStack)
{
Action(player, deck);
}
}
等等
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.