【问题标题】:c# preventing inheritance of a methodc# 防止方法的继承
【发布时间】:2011-02-17 05:24:00
【问题描述】:

对于扑克解析器(我学习 c# 的第一个项目),我有一个父类 clCardsHeld 和两个子类 clHiHandclLoHandclCardsHeld 还包含两个子类型中的每一个的属性和私有字段。所以我最终得到的,是这个继承,例如:

public class clCardsHeld
{public clHiHand HiHand { Get {} Set {} }
} 
public class clHiHand : clCardsHeld{}

clCardsHeld Hand3 = new clCardsHeld(); 
clHiHand hi = new clHiHand(); 
hi = Hand3.HiHand.HiHand.HiHand; 
hi = Hand3.HiHand.LoHand.HiHand;

(由智能感知提示)。 (HiHand 不应该有另一个 HiHand 作为它自己的属性,也不应该是低手。但是 CardsHeld 有一个 HiHandLoHand 作为属性,例如,你得到 7 张牌的游戏,你可以用 5 做最好的牌,用 5 做最坏的牌,两者同时玩,各占一半底池。)

我将基类字段设为私有,而不是受保护,因此如果我没看错的话,继承的属性仍然是null。但我真的希望财产不要被继承。尝试对此进行研究,我发现只有在覆盖基本属性时才能密封属性。而“隐藏”的方法一般是指在孩子身上有不同的代码......

另一件事,当我抛出我的新手问题时:

    public class clCardsHeld { private List<clCards> _liCards; }
public class clHiHand : clCardsHeld 

我可以在本地窗口中找到clCardsHeld._liCards,但我在本地窗口中找不到clCardsHeld.clHiCards._liCards(但我可以通过将其分配给变量来获取它。

感谢您的帮助。

【问题讨论】:

  • 查看这个重复的问题:stackoverflow.com/questions/3772321/…
  • 请提供一些示例源代码。
  • 我至少尝试了两次来阅读这篇文章,但我就是不能。我不知道你在问什么。你能更好地格式化你的问题吗?更多的空格(想想段落)和代码格式将有助于很多。你所要做的就是用 4 个空格来设计你的代码行,它们会自动显示语法高亮和其他好东西。
  • 我同意副本中的答案。使用组合而不是继承。
  • 感谢您的链接。我看到了那个,但它并没有因为它与我有关。试图继承 Collection 似乎来自与我不同的困惑。我有很多代码可以将字符串输入解析为卡片对象和列表,我希望这些代码对父母和孩子来说都是通用的。而且我想有时我希望能够实例化一个特定的 5 张 HiHand 或 LoHand。但让我再考虑一下您的建议。

标签: c# inheritance encapsulation


【解决方案1】:

正如 Adeel 引用的链接中提到的,这种情况下的继承是不必要的。你的高手和低手应该只是 clCardsHeld 的新实例:

public class clCardsHeld
{
    private List<clCards> _liCards;

    public clCardsHeld GetLoHand()
    {
        //Logic here for returning the low hand, using _liCards
    }

    public clCardsHeld GetHiHand()
    {
        //Logic here for returning the high hand, using _liCards
    }
}

GetLoHand() 和 GetHiHand() 函数将简单地返回一组不同的持牌。

【讨论】:

  • 谢谢。这很简单,也很明智。
【解决方案2】:

您的帖子中有几个误解..

  • 如果您不希望某个属性被继承,则您违反了Liskov Substitution Principle
  • 子类中的字段不为空,因为它们是基类私有的。它们仍然可以由基类中的逻辑分配。
  • 在我看来,您在不需要时使用继承。当概念(子类)是另一个概念(基类)的特例时,请使用继承。并且喜欢组合而不是继承。

我认为您应该将所有对象共有的部分拆分为一个单独的基类:

class HandBase { /* common to both HiHand an LoHand */}
class LoHand : HandBase {}
class HiHand : HandBase {}

从您的解释中我可以看出,cCardsHeld 不必具有相同的基本类型:

class CardsHeld
{
    public LoHand LoHand { get; private set;}
    public HiHand HiHand { get; private set;}
}

但如果是这样,那么你可以这样做:

class CardsHeld : HandBase
{
    public LoHand LoHand { get; private set;}
    public HiHand HiHand { get; private set;}
}

如果有一个你不希望子类拥有的属性,那么不要将它放在基类中。

【讨论】:

  • 哦,让我澄清一个关于 null 的问题。我认为我遇到的问题是试图将基类中的属性保留在派生类之外。我没有做到这一点(现在明白这是错误的想法),但我所做的是将对“问题”属性背后的字段的访问更改为私有。这似乎具有这样的效果:属性(“.HiCards.HiCards”)的不受欢迎的继承实例全部返回为空。我就是这个意思。
  • 更改访问修饰符不会影响字段的值。但是您可能不得不注释掉或删除一些为其分配值的代码,以便在更改修饰符后使其编译。这可能就是现在为空的原因。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-12
  • 2017-12-22
  • 2011-04-15
  • 1970-01-01
  • 1970-01-01
  • 2018-10-31
相关资源
最近更新 更多