【问题标题】:Inheritance or enum继承或枚举
【发布时间】:2011-03-07 16:33:41
【问题描述】:

我必须为应用程序构建新模型,但我没有更好的方法:

使用继承或使用枚举作为对象类型:

例如:

书籍

class Book
{
public string Name {get;set;}

public string Author {get;set;}

public int NumberOfPages {get;set;}

}

public class Encyclopedie:Book
{

}

public class Novel:Book
{

}

或更好的用法:

class Book
{

public BookType Type {get;set;}

public string Name {get;set;}

public string Author {get;set;}

public int NumberOfPages {get;set;}

}

public enum BookType
{
Encyclopedie = 0,
Novel = 1,
...
}

【问题讨论】:

    标签: c# inheritance modeling


    【解决方案1】:

    如果不同类型有显着差异(您如何处理和对待它们),请使用继承。也就是说,如果你要使用多态,你应该使用继承。

    如果您只需要一种方法来区分不同类型的书籍,请使用 Enum。

    【讨论】:

    • 完全同意。刚才我在想如何表达“显着差异”。英语不好:(
    • 同意。似乎他只想将它视为不同的类型。继承产生了强耦合,当你拥有一本跨流派的书时会发生什么?切换到 C++ 以允许多重继承? [Flag]'ed 枚举在这里可能是一个不错的选择。
    【解决方案2】:

    在真正的面向对象系统中,对象的类型对客户端是透明的。所以处理书的代码不应该知道书的类型,而只是调用书上的方法。

    因此,如果您需要在 book 中实现不同的行为以响应方法调用,请扩展 Book 并覆盖它的一些方法。如果你不这样做,那就不要。

    看起来,鉴于您的子类的空体,它们在各方面的行为都与书籍相同。所以你只是用一些额外的数据来标记这本书 - 百科全书和小说之间的区别对于这本书来说并不比精装或软装或大字体或标准印刷更重要 - 客户可能会以不同的方式使用这些,每本书要么是大印刷书或者是标准印刷书,但这些都是书的属性,而不是本质的区别。

    我不需要为书的种类使用枚举,因为您可能想要添加更多数据 - 我会使用松散的标记系统,这样您就可以用各种类型的集合标记一本书 - 所以你会有一本书被标记为 { 'children's', 'ornithological', 'encyclopaedia', } - 或允许角色中的结构 - 因此在需要时创建“儿童鸟类百科全书”的角色,但没有固定的枚举。

    【讨论】:

      【解决方案3】:

      我会说第二个会更好,因为您并没有真正扩展百科全书中的书籍类,您不需要为一种书籍类型提供​​其他属性或功能。

      【讨论】:

        【解决方案4】:

        “最佳”是主观的,很大程度上取决于类/模型的目的。 你的目标是什么?你想达到什么目标?

        在这一点上,我最多只能说,当派生类具有一些相当独特的属性时,继承是有用的——比如 Encyclopedie 具有解释它实际上是哪种类型的 Encyclopedie 的属性,而这些属性无论如何都不属于一本小说。

        【讨论】:

          【解决方案5】:

          这真的取决于。如果您需要使用多态性,第一个解决方案会更好。从我个人看来,我更喜欢使用继承。

          【讨论】:

            【解决方案6】:

            如果不同类型的书有不同的属性,你肯定应该使用继承模型。这也允许多态性,这通常更好

            如果它们都具有相同的属性,您最好使用枚举。但这一切都取决于应用程序。

            【讨论】:

              【解决方案7】:

              我认为你应该根据这本书的“目的”来做出这个选择。如果书籍不需要任何额外的东西(方法和属性......)枚举应该就足够了。如果您必须为每本书创建一个共同的行为,并且为每种书籍类型创建其他更具体的行为,那么您显然需要继承(抽象类“书”和具体类)。

              【讨论】:

                【解决方案8】:

                使用枚举“键入”您的对象听起来有点“旧 C 风格”编程。

                我的意思是,这没关系,但是当继承可用时(您使用的是 C#),它通常是一个更好的选择。枚举通常会引入一些“麻烦”,例如在序列化/反序列化数据时:如果您的应用程序的旧版本使用 BookType 具有未知项目的“较新”场景怎么办? (向后/向前兼容性可能是您的应用程序的要求)

                当然,您可以使用“if-then-else”来处理这个问题,但在我看来,继承似乎是一个更干净的选择。

                再见!

                【讨论】:

                • 反序列化数据时如何区分继承的类?我看到的唯一方法是在序列化对象的每个实例中包含类名(您也可以通过在枚举上调用 tosting() 来完成)
                • 一个 XmlSerializer 返回类型化的数据——当然你可以使用一个枚举并打开它,但是当“类型”已经提供了同样的东西时,为什么要这样做呢?另外:如果您只使用单个类和“枚举”来键入它,则必须将 all 各种类型所需的属性放入该类中。您可能会拥有“BookAAA”类型需要的属性“XYZ”,但“NovelBBB”类型不需要 - 恕我直言,当您可以通过继承来避免这种情况时,这不是很好。
                猜你喜欢
                • 2010-10-19
                • 2016-01-16
                • 2012-04-04
                • 1970-01-01
                相关资源
                最近更新 更多