本页使用了标题或全文手工转换

泛型

维基百科,自由的百科全书
跳转至: 导航搜索

泛型程序设计程序设计语言的一种风格或范式。允许程序员在强类型程序设计语言中编写代码时使用一些以后才指定的类型,在实例化时(instantiate)作为参数指明这些类型。各种程序设计语言和其编译器、运行环境对泛型的支持均不一样。Ada, Delphi, Eiffel, Java, C#, F#, Swift, and Visual Basic .NET称之为泛型(generics);ML, Scala and Haskell称之为参数多态(parametric polymorphism);C++D称之为模板。具有广泛影响的1994年版的《Design Patterns》一书称之为参数化类型(parameterized type)。

泛型的定義及目的[编辑]

泛型的定義主要有以下兩種:

  1. 在程序编码中一些包含类型参数的类型,也就是说泛型的参数只可以代表类,不能代表个别对象。(这是当今较常见的定义)
  2. 在程序編碼中一些包含參數的。其參數可以代表类或对象等等。(現在人們大多把這稱作模板)

不論使用那個定義,泛型的參數在真正使用泛型時都必須作出指明。

一些强类型程序语言支持泛型,其主要目的是加强类型安全及减少类转换的次数,但一些支持泛型的程序语言只能达到部份目的。

偽代碼例子[编辑]

類 例泛類<T> {
  值 : T
 
  設置值(新值 : T) {
    值 := 新值
  }
 
  獲取值() : T {
    返回 值
  }
}
 
例方法1() {
  例物件 : 例泛類<整數型>
  例物件 := 新 例泛類<整數型>()
  例物件.設置值(5)
  输出整数(例对象.获取值())
}
 
例方法2() {
  例物件 : 例泛類<浮點數型>
  例物件 := 新 例泛類<浮點數型>()
  例物件.設置值(5.5)
  输出浮点数(例对象.获取值())
}

在這例子中,例泛類是一個泛型,而T是一個類型參數。在例泛類中沒指明T的實際類型,只有例方法1()例方法2()在使用例泛類時才加以指明。

運行這例子的例方法1()將輸出整數5,而運行例方法2()將輸出浮點數5.5。

一些程序语言的泛型特性[编辑]

.NET Framework的泛型[编辑]

.NET Framework泛型的参数只可以代表类,不能代表个别对象。由于.NET Framework泛型的类型参数之实际类型在运行时均不会被消除,运行速度会因为类型转换的次数减少而加快。另外,使用GetType()方法可于程序运行时得知泛型及其类型参数的实际类型,更可以运用反射编程。

.NET Framework允許對個別泛型的類型參數進行約束,包括以下幾種形式[1](假設T是泛型的類型參數,C是一般类、泛類,或是泛型的類型參數):

  • T是一個类。
  • T是一個值類型。
  • T具有無參數的公有建構方法。
  • T实现界面I
  • TC,或繼承自C

Java的泛型[编辑]

Java泛型的参数只可以代表类,不能代表个别对象。由于Java泛型的类型参数之实际类型在编译时会被消除,所以无法在运行时得知其类型参数的类型。Java编译程序在编译泛型时会自动加入类型转换的编码,故运行速度不会因为使用泛型而加快。

Java允許對個別泛型的類型參數進行約束,包括以下兩種形式[2](假設T是泛型的類型參數,C是一般类、泛類,或是泛型的類型參數):

  • T实现界面I
  • TC,或繼承自C

C++的泛型(模板)[编辑]

C++泛型的参数可以代表类或个别对象。C++无法对泛型的类型参数进行约束。在编译时,每个被使用的封闭泛型类型(即是所有泛型参数的实际类型都已被指明的泛型)都会有独立的编码产生,编译程序会在此时确保类型安全性。可是如果泛型要运用其泛型参数的某成员,而该泛型参数又不包含该成员的时候,编译程序所产生的错误信息或会看似与实际问题无关,增加除错的难度。

数据源[编辑]

  1. ^ Standard ECMA-335 Common Language Infrastructure (CLI) 4th Edition. June 2006. 
  2. ^ James Gosling, Bill Joy, Guy Steele, Gilad Bracha. The Java Language Specification Third Edition. 2005.