c#抽象继承设计问题

c#抽象继承设计问题,c#,inheritance,abstract,C#,Inheritance,Abstract,我对C#有些陌生,我正努力按照OO原则做好工作,并编写好代码。在花了几个小时寻找我的问题后,我找到了一些模糊的答案,但没有一个足够让我自信的答案。我很有可能问了一个愚蠢的问题,并从错误的角度来处理这个问题 我的问题是:假设我想创建一个抽象的基本卡片类,从中我可以编写任何纸牌游戏(例如,让我们比较一组基本的扑克牌和魔术:聚会)。接下来,我能够创建一个PokerCardType,它基本上是标准牌组中每张牌的美化枚举。我的问题源于如何创建一个抽象的Card类,该类需要CardType的实例,但具体实例

我对C#有些陌生,我正努力按照OO原则做好工作,并编写好代码。在花了几个小时寻找我的问题后,我找到了一些模糊的答案,但没有一个足够让我自信的答案。我很有可能问了一个愚蠢的问题,并从错误的角度来处理这个问题


我的问题是:假设我想创建一个抽象的基本卡片类,从中我可以编写任何纸牌游戏(例如,让我们比较一组基本的扑克牌和魔术:聚会)。接下来,我能够创建一个PokerCardType,它基本上是标准牌组中每张牌的美化枚举。我的问题源于如何创建一个抽象的Card类,该类需要CardType的实例,但具体实例尚未确定。我的第一个想法是创建一个抽象的CardType类,对于任何子类都需要一组静态CardType对象,但我不知道如何做到这一点。我的另一个问题是,这个想法真的有意义吗,或者我应该创建两个独立的类结构,一个用于扑克,一个用于魔术。如果你想知道我为什么要这么做,那真的只是为了我自己的教育。感谢您提供的帮助或任何链接。

听起来您希望有一个静态CardType类,它可以用您想要支持的一组卡实例来定义。如果这对您来说不够动态,那么它仍然可以是一个静态类,它知道所有已注册的卡类型。

我认为您走错了路。遵循OO原则和编写好代码有相当多的重叠,但方式不同。不要试图遵循OO原则,因为有人告诉过你。跟随它们,因为它们适合你解决实际问题的需要。通常的形状->圆形/矩形->绘图示例是不可见的,令人困惑

很难总结,但我会尝试:要实现一些抽象类,您需要一个好的抽象。像“卡片”这样的东西并不是抽象概念。抽象将是您可以使用卡执行的操作。这些操作显然取决于上下文,因此在不同的上下文(程序)中,您可能会对“卡片”产生不同的良好抽象


如果这是为了你的教育:实现一个扑克游戏没有任何花哨的OO东西。然后在没有任何奇特的OO东西的情况下实现魔术。看看他们有什么共同点。尽量消除重复。现在您将发现一些OO原则非常有用。卡片的抽象将自动演变。

我将进一步细分需求。你想用一个基类来表示扑克和魔术中的牌是什么?除了高度和宽度尺寸外,它们在各自游戏中的使用方式几乎没有共同之处。扑克牌不能被攻破。魔术卡不能用来组合同花顺。这些卡片本身没什么作用

我想他们可以洗牌。。。如果您想对此进行建模,您可以创建一个两个类都可以实现的IShuffileble接口

要直接回答我认为您在问的问题,您可能可以使用泛型来解决它。假设你想要一副牌:

public class CardDeck<T> : where T:BaseCardType
{
   private List<T> _cards new List<T>();

   public void Shuffle()
   {
      // blah blah
   }

   public void SomethingElseYouCanDoWithADeck
   { }
}
公共类卡片组:其中T:BaseCardType
{
私人列表_卡新列表();
公开无效洗牌()
{
//废话
}
公共空间中的一些东西你可以用Adeck
{ }
}

我只是觉得这对你没有多大帮助。。。您能否详细说明一下,一旦设计好这些类,您将如何使用它们?

您在这里做的抽象太多了。除非你正在设计一个非常通用的纸牌游戏引擎(我的意思是非常通用的),否则我看不出有任何理由认为一副扑克牌和一副魔术牌对于某些抽象类来说是“一副
牌”

从最简单的事情开始

class PokerDeck { }
class MagicDeck { }
如果以后发现它们有足够的共同点来提取抽象基类
Deck
,那么就这样做。我的观点是,你不太可能发现这种情况。你当然可以尝试,但这很可能只是一个巨大的心理自慰练习,收获甚微


注意:继承是最容易被误解和误用的OOP概念

抽象类和继承的概念是指接近同一事物的类。通常情况下,子类是“定义得更好”或“更具体”的实例,而不仅仅是基本类型


例如:警车是轿车的一个更具体的版本,因此警车将继承轿车。但是MTG卡不是扑克卡的更具体的实例,反之亦然。对于某些纸牌游戏,例如扑克卡和Uno卡,您可能可以这样做,因为它们具有相同的特征,如面值和套装/颜色。

这里是一个抽象类组的示例,其中包含扑克组和MagicDeck的具体实现。正如其他人所说,我不确定这是否是最好的例子,因为这两款游戏之间确实没有太多共同之处

也许如果你做一些像《黑桃手》、《心之手》、《皮诺奇兰德》、《总统之手》这样的事情,你会在每只手上都有各种各样的卡片。每个游戏都有一个“PlayNextCard”的方法,它们有不同的规则,但都围绕着将手上的一张牌放在一个普通的牌堆上

public abstract class Deck
    {
          public int NumberOfCards{get; private set;}

          public IEnumerable<Card> Cards {get; private set;}

          public void Shuffle()
          {
              Cards = RandomizeCards();
          }

          protected abstract IEnumerable<Card> CreateCardList();

    }

    public class PokerDeck
    {
         public PokerDeck()
         {
              NumberOfCards = 52;
              Cards = CreateCardList();
         }
    }

    public class MagicDeck
    {
         public MagicDeck()
         {
             NumberOfCards = 10000; // have no idea
              Cards = CreateCardList();
         }
    }
公共抽象类组
{
公共int NumberOfCards{get;private set;}
公共IEnumerable卡{get;private set;}
公开无效洗牌()
{
卡片=随机卡片();
}
受保护的抽象IEnumerable CreateCardList();
}
公共级扑克牌组
{
公共扑克牌组()
{
卡片数量=52;
Ca