什么是 Type Class ?
Type Class (类型类) 的概念来自 Haskell,表示一系列函数的集合,在概念上, Type Class 和面向对象领域的泛型接口比较类似。
由于 Haskell 是一门纯函数式编程语言,没有类和接口的概念,所以使用 Type Class 表达类似接口的概念。例如 Haskell 的 Ord 类型类在概念上和 Java 的 Comparable 非常类似。
在 Haskell 中,Type Class 使用 class
关键字定义:
class BasicEq a where
isEqual :: a -> a -> Bool
isEqual x y = not (isNotEqual x y)
isNotEqual :: a -> a -> Bool
isNotEqual x y = not (isEqual x y)
Type Class Instance 则使用 instance
关键字定义:
instance BasicEq Bool where
isEqual False False = True
isEqual True True = True
isEqual _ _ = False
只要定义了 Bool 类型的 Type Class Instance,我们就可以在任何地方使用 isEqual 方法比较 Bool 类型的相等性。用面向对象的语言描述就是:Bool
类型实现了 BasicEq
接口。
Type Class 的好处是,当系统增加一个新类型时,只需要实现该新类型的 Type Class Instance 即可,已有类型代码可以保持不变。
Java中的 Type Class
在面向对象领域使用接口解决类似 Type Class 的问题,例如 Java 的 Comparable 接口。但是接口的方式并不优雅,它要求新类型必须实现 Comparable 接口,如果这个新类型来自第三方库,我们无法强制要求它实现 Comparable 接口。所以在面向对象领域,我们仍然可以借鉴 Type Class 的方式以解决接口所面临的问题。所以 Java 提供了一个 Type Class 的等价物,即 Comparator<T>
接口,所有实现了Comparator<T>
接口的实例即为 Type Class Instance。针对一个新类型Person
,我们只需要实现一个Comparator<Person>
实例,即可以在任何地方对Person
集合进行排序。
Scala 中的 Type Class
同样的,Scala 的核心库设计中也采用了 Type Class 的概念。例如Ordering[T]
是一个 Type Class, IntOrdering
是一个 Type Class Instance。所以只要有IntOrdering
实例,我们就可以对Int类型进行排序:
def sorted[B >: A](implicit ord : scala.math.Ordering[B])
由于Ordering
中已经预定了常见的Type Class Instance 的隐式对象,所以我们可以在任何地方对常见类型进行排序。