【问题标题】:Generic Types vs Abstract class/Interfaces泛型类型与抽象类/接口
【发布时间】:2010-11-08 23:28:19
【问题描述】:

假设我们在 .NET 中创建一个通用控件。例如。一颗树。 我不明白为什么人们使用这个泛型类型定义

Control<T>

在面向对象编程中,我可以使用抽象类或接口:

Control<IItem> or Control<BaseClass>

所以唯一要做的是,它们的类型必须从该基类派生或实现 界面。 是不是说,泛型更方便,因为你我不用实现或继承任何东西?

【问题讨论】:

    标签: generics interface abstract-class


    【解决方案1】:

    我觉得你有点困惑。泛型类型和抽象类/接口为应用程序设计中的不同方法提供不同的目标。抽象类/接口用于泛化一组实体的通用功能。稍后这个 API 可能会以不同的方式实现,但由于涉及多态性,它不会影响任何人。

    另一方面,有时您对某些东西的实现非常相似,唯一的区别是您正在使用的对象的类型。在这里,您将需要一个泛型。您可以使用多态性,但没有必要。为此目的,只需定义一个接口、实现一个实现并让最终用户决定使用哪种对象就更清楚了。

    最好的例子是 List,其中 list 的主要用途是存储元素。 List 实现者不应该关心您将使用哪种类型的对象,因此稍后您将能够只定义 List 并使用整数列表。

    【讨论】:

    • 好的,现在我明白其中的区别了,非常感谢。
    【解决方案2】:

    因为在您的树控件的情况下,定义通用树控件意味着树项目可以是任何类型(您也可以添加某些约束)。

    当实例化一个控件时,您当然必须声明您的项目类型(例如在您的第二个代码示例中使用IItemBaseClass)。

    如果您的 Tree 控件不是泛型类型,则必须为每个项目类型创建多个控件。

    为什么不直接使用 interface/abstractBase 类型?
    如果您只使用接口/抽象作为您的 Item 具体类,您将受到它的定义的限制。你只会看到它的属性和方法。使用通用 Tree 控件和任何项目类型,您仍然可以访问所有项目的属性和方法,而不管其接口实现或父类继承...

    【讨论】:

    • 但是我还有 1 个问题,如果我想将类型 T 限制为具有 Parent 和 Children 属性并且我不使用接口怎么办。有可能吗?
    • @stefan - 约束必须通过接口来表达,除了一些简单的事情:它是一个值类型(where T : struct),或者一个引用类型(where T : class),或者它有一个默认构造函数 (where T : new())
    • @stefan:当然,您也可以在没有接口的情况下这样做,只要您定义一个具有这两个属性的类并且您的项目类从它继承。但是使用接口通常要容易得多,因为一个类可以实现多个接口但只能继承一个。
    • ...只继承一个类。对不起。
    猜你喜欢
    • 2021-12-15
    • 2020-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-10
    • 1970-01-01
    • 1970-01-01
    • 2012-04-11
    相关资源
    最近更新 更多