`
alanwu
  • 浏览: 197312 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

泛型参数 V.S. 抽象类型成员

阅读更多

 

 

by Bill Venners
October 7, 2009

http://www.artima.com/weblogs/viewpost.jsp?thread=270195

 

摘要:

在这篇博客中,作者试图回答Scala编程中一个共同的问题:在Scala API设计时,什么时候用泛型参数,什么时候用抽象类型成员。

 

---------------------------------------------------------------------------------------------

学习Scala建一个抽象类型模型的时,一个普遍的问题是如何决定使用泛型参数,还是抽象类型成员。对于不熟悉这两则区别的人来说,Scala的泛型参数有点像Java的泛型参数,只是Java用尖括号,而Scala用方括号。

 

Java泛型 

interface Collection<T> {
    // ...
}
 

 

Scala泛型使用方括号 

// Type parameter version
trait Collection[T] {
  // ..

}
 

Scala的抽象类型成员(Abstract type members)没用和Java等同的。 两个语言中,类,接口(Java),特征(Scala)都可以有方法和字段作为成员。Scala的类或特征(trait)可以有类型成员,下面例子是抽象类型成员:

 

// Type member version

trait Collection {
  type T
  // ...
}

 

这两种情况,抽象类型都可以在子类中具体化。下面的例子中子类用String具体化了类型参数T:

// Type parameter version

trait StringCollection extends Collection[String] {
  // ...
}

 

或者在子类内部具体化类型参数T:

 

// Type member version
trait StringCollection extends Collection {
  type T = String
  // ...
}

 

这看上去,事实上也是,有两种不同的方法达到同一个目的。那么我们怎么做选择呢?我在采访Martin Odersky(Scala创始人)的时候问了这个问题,他最先解释了同时有这两种方法是正交的。

Martin Odersky 写道
总是有两种对抽象的观念:
参数化和抽象成员。Java也有可以同时有这两个,但这取决于你想抽象什么。
用Java你可以有抽象方法,但你不能将方法当作参数。你不能有抽象字段,但可以将传递参数。简单将你可以没用抽象类型成员,但你可以将具体的类型当参数。所以用Java你也可以有这三种方式,只是你在做不同类型的事情时的抽象原则有所不同。你可以说这些差异是简直是专制。

我们试图让Scala在抽象方面变得完全和正交。我们决定对所有这三种成员(类型,字段,方法)的抽象有统一的构造原则。你可以像值参数那样有抽象字段。你可以像参数一样传递方法(或叫函数),或者你能抽象他们。你可以像参数那样具体化类型,或者抽象他们。我们可以在概念上为其他建立一个模型(we can model one in terms of the other)。至少在原则上,我们能对每个不同的参数化做统一的OO抽象。所以在一定意义上说,Scala是更充分和正交(orthogonal )的语言。

 

他同时解释了抽象类型成员和泛型参数在实际应用中的不同:

 

Martin Odersky 写道
在实际应用中,当你在不同时候使用类型参数时,会暴露参数,甚至参数边界(bounds of parameters)。在1998年ECOOP,Kim Bruce, Phil Wadler和我在一篇文章中展示了当你在不知道的情况下增加的东西会编程二次方。所以这是个很好的理由不要参数,而使用抽象成员,因为他们不会给你成倍的增加。
 当Martin给我这个答案的时候,我并不确认是不是真的理解了他所讲的,但是现在我可以给出更多的不同点。我总是倾向于使用泛型参数,因为我来自C++和Java背景,更加熟悉类型参数化和类型成员。尽管如此,我遇到一个设计问题,我使用了抽象类型成员解决了问题,而不是泛型类型参数。
 这个问题是当我设计ScalaTest时想提供traits让用户写的测试能传入特定的对象。这可以给大家选择使用函数编程方式写测试,而不只是像命令式的JUnit中的setUp,tearDown方法。要提供这种选择,我需要让用户能通过具体类型参数或者成员来指示特定对象的类型。换句话说,我要在ScalaTest API中提供这样的trait.
// Type parameter version
trait FixtureSuite[F] {
  // ...
}
或者:
// Type member version
trait FixtureSuite {
  type F
  // ...
}
一种情况是,F是特定参数穿入的,suite的子类需要提供具体类型。这里的测试具体子类需要将StringBuilder传入到每个测试,使用类型参数达到这个目的:
// Type parameter version
class MySuite extends FixtureSuite[StringBuilder] {
  // ...
}
 同时另一个例子是将StringBuilder当作抽象类型成员值传递给每个测试:
// Type member version
class MySuite extends FixtureSuite {
  type F = StringBuilder
  // ...
}
 
So far there's not much difference. However, one other use case I had is that I wanted to allow people to create traits that provide a concrete definition for the fixture type and could be mixed into suite classes. This would allow users to encode commonly used fixtures into helper traits that could be mixed into any of their suite classes that need them. This is where a difference showed up. Here's how you'd write that trait using the generic type parameter approach:



分享到:
评论
1 楼 alanwu 2009-10-17  
还没翻完,希望在下周翻译完毕。

相关推荐

    11.java接口和抽象类的区别.zip

    11.java接口和抽象类的区别.zip11.java接口和抽象类的区别.zip11.java接口和抽象类的区别.zip11.java接口和抽象类的区别.zip11.java接口和抽象类的区别.zip11.java接口和抽象类的区别.zip11.java接口和抽象类的区别....

    10.java接口和抽象类的相似性.zip

    10.java接口和抽象类的相似性.zip10.java接口和抽象类的相似性.zip10.java接口和抽象类的相似性.zip10.java接口和抽象类的相似性.zip10.java接口和抽象类的相似性.zip10.java接口和抽象类的相似性.zip10.java接口和...

    Abstract Java game library based on JavaFX. 基于JavaFX的抽象Java游戏库

    基于JavaFX的抽象Java游戏库 Abstract Java game library based on JavaFX. 基于JavaFX的抽象Java游戏库 Abstract Java game library based on JavaFX. 基于JavaFX的抽象Java游戏库 Abstract Java game library ...

    2.java使用抽象类.zip

    2.java使用抽象类.zip2.java使用抽象类.zip2.java使用抽象类.zip2.java使用抽象类.zip2.java使用抽象类.zip2.java使用抽象类.zip2.java使用抽象类.zip2.java使用抽象类.zip2.java使用抽象类.zip2.java使用抽象类.zip...

    5.java使用抽象类.zip

    5.java使用抽象类.zip5.java使用抽象类.zip5.java使用抽象类.zip5.java使用抽象类.zip5.java使用抽象类.zip5.java使用抽象类.zip5.java使用抽象类.zip5.java使用抽象类.zip5.java使用抽象类.zip5.java使用抽象类.zip...

    4.java使用抽象类.zip

    4.java使用抽象类.zip4.java使用抽象类.zip4.java使用抽象类.zip4.java使用抽象类.zip4.java使用抽象类.zip4.java使用抽象类.zip4.java使用抽象类.zip4.java使用抽象类.zip4.java使用抽象类.zip4.java使用抽象类.zip...

    3.java使用抽象类.zip

    3.java使用抽象类.zip3.java使用抽象类.zip3.java使用抽象类.zip3.java使用抽象类.zip3.java使用抽象类.zip3.java使用抽象类.zip3.java使用抽象类.zip3.java使用抽象类.zip3.java使用抽象类.zip3.java使用抽象类.zip...

    1.java定义抽象类.zip

    1.java定义抽象类.zip1.java定义抽象类.zip1.java定义抽象类.zip1.java定义抽象类.zip1.java定义抽象类.zip1.java定义抽象类.zip1.java定义抽象类.zip1.java定义抽象类.zip1.java定义抽象类.zip1.java定义抽象类.zip...

    数学丛书.-.[抽象代数学卷3].[.域论及伽罗瓦理论]

    域论及伽罗瓦理论 是 抽现代数的理论知识 pdf格式

    01.算计概述与抽象数据类型.rar

    JAVA算法:01.算计概述与抽象数据类型.rar 有ppt与源码与教学视频

    J2SE技术总结-Java学习精华教程-电子书

    变量与数据类型 ..........标识符 ..........运算符 ..........控制台输入输出 ..........流程控制 ..........数组的使用 .....字符串和正则表达式 ..........字符串 ..........正则表达式 .....类和对象 .............

    29编程范式游记(2)-泛型编程1

    1. 算法的泛型 2. 类型的泛型 3. 数据结构(数据容器)的泛型 1. 使用模板技术来抽象类型,这样可以写出类型无关的数据结构(数据容器) 2. 使用一个迭

    微软 C#语言参考 CHM格式

    17.1.3 属性参数类型... 248 17.2 规范... 249 17.3 属性实例... 251 17.3.1 一个属性的编译... 251 17.3.2 一个属性实例的运行时检索... 252 17.4 保留的属性... 252 17.4.1 AttributeUsage 属性... 252 17.4.2 ...

    C++编程-数据结构与程序设计方法[美.D.S.Malik][中译本]

    8. 用户自定义简单数据类型、名字空间和string类型 9. 数组和字符串 10.递归 11.结构 12.类和数据抽象 13.继承和组成 14.指针、类、表及虚函数 15.重载与模板 16.链表 17.栈和队列 18.查找和排序算法 19.二叉树 20....

    C#教程(语言规范)

    7.5.2.7 参数类型显式推断 ... 129 7.5.2.8 精确推断 ... 129 7.5.2.9 下限推断 ... 129 7.5.2.10 固定 .. 130 7.5.2.11 推断返回类型 .. 130 7.5.2.12 方法组转换的类型推断 131 7.5.2.13 查找一组表达式的最...

    虚拟数据层 Struts2、Hibernate、Spring整合的泛型DAO Version 2010.9.27

    泛型 泛型类型的限定 3.反射 代码概述: bean :Person.java 这个人员类我就不说了 泛型dao接口 :GenericDao, ID extends Serializable&gt; 泛型作为DAO的通用接口 CRUD方法 dao接口 : PersonDAO extends ...

    gson-2.8.6.jar下载

    gson-2.8.6.jar下载,gson是Google开发的一款优秀的Java JSON解析库。它可以将Java对象转换成JSON字符串,也可以将JSON字符串转换成...8. 高性能:gson通过流式API、缓存策略以及基于类型的Maass抽象序列化类来提高性能。

    129.C++ 接口(抽象类).txt

    129.C++ 接口(抽象类).txt

    java面试题.pdf

    10道Java面试题及详细解答 1.Java中多态的实现方式是什么?...6. Java中抽象类和接口的区别是什么? 7. Java中什么是异常? 8. Java中如何防止对象的clone? 9. Java中什么是泛型? 10. Java中如何实现单例模式?

Global site tag (gtag.js) - Google Analytics