泛型类型 vs 抽象类/接口

8

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

Control<T>

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

Control<IItem> or Control<BaseClass>

所以唯一需要做的就是,它们的类型必须派生自该基类或实现该接口。 这是否意味着泛型类型更方便,因为我不需要实现或继承任何内容?

2个回答

22

我觉得你可能有一点困惑。泛型和抽象类/接口在应用设计中各有不同的目标。抽象类/接口是为了将一组实体的共同功能进行概括。随后 API 可以以不同的方式进行实现,但由于涉及到多态性,因此不会影响任何人。

另一方面,有时你会有非常相似的某些实现,唯一的区别就是你所使用的对象类型。这时你就需要泛型。你可以使用多态性,但没有必要。为此,最清晰的方法就是定义一个接口,做出一个实现,让最终用户决定使用哪种类型的对象。

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


1
好的,现在我明白了这个区别,非常感谢。 - theSpyCry
1
我来自未来,感谢你的解释:D - franco

3

因为在您的树形控件案例中,定义一个通用的树形控件意味着树形项目可以是任何类型(您还可以添加某些限制)。

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

如果您的树形控件不是通用类型,那么您将不得不为每种项目类型创建几个控件。

为什么不只使用接口/抽象基类?
如果您只使用接口/抽象作为您的项目具体类,您将受到它的定义的约束。您只能看到它的属性和方法。使用通用树形控件和任何项目类型,您仍然能够访问所有项目的属性和方法,而不管其接口实现或父类继承...


但是我还有一个问题,如果我想限制类型T具有Parent和Children属性,而且我不使用接口,这是否可能? - theSpyCry
@stefan - 约束必须通过接口表达,除了一些简单的事情:它是值类型(where T : struct),还是引用类型(where T : class),或者它具有默认构造函数(where T : new())。 - Daniel Earwicker
@stefan:当然,你也可以不使用接口来实现这个,只要你定义一个包含这两个属性的类,并且你的项目类从它继承即可。但是通常使用接口会更容易一些,因为一个类可以实现多个接口,但只能继承一个。 - Robert Koritnik
只能继承一个类。抱歉。 - Robert Koritnik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接