1

我想知道,这两者有什么区别:

class SomeClass(val a: Int)

//1
class Class1[T <: SomeClass] {
  def method1(param1: T) = ....
}

//2
class Class2 {
  def method1(param1: SomeClass) = ....
}
4

2 回答 2

3

功能上?说明为什么某些 3rd-party 代码有可能加载这些类将执行以下操作:

class ThirdPatyClass(val a: Int) extends SomeClass(a) with ThirdPartyTrait

Class1[ThirdPartyClass]可以使用(和具体化的对应)的实例,method1其中将存在表单的类型绑定

[S <: ThirdPartyTrait]

Class2不能。

而且,当然,根据您在这些方法中所做的事情,您T可以在.TClass[_ <: T]Class1.method1

通常,Class1您为编译器(和开发人员)提供了param1保留Class2更多param1关于SomeClass.

编辑:从评论中回答问题 - 是的,是选择一种方法还是另一种取决于您的需要。如果您需要更多的灵活性和更多的静态类型信息,请使用泛型类型边界。如果没有,我会说你应该遵循YAGNI而不是弄乱你的 API。

于 2013-09-12T06:07:17.703 回答
1

Class2既是类又是类型,而Class1只是类。永远不会有带有 type 的值Class1,尽管可以有任意数量的参数化类型(Class1[SomeClass], Class1[SomeSubClass1], Class1[SomeClassType2] 等),所有这些类型都具有相同的类,并且在运行时只能根据Class1[_]类型来识别擦除。这有一些实际效果:

  1. 类型擦除使模式匹配复杂化。
  2. 类型擦除也使得各种反射技术Class1Class2.
  3. 子类化Class1需要更多的思考,因为必须考虑方差问题。

另一方面,因为Class1是参数化的,所以很容易混合任意一组特征,并且知道它们都可以安全地应用于同一类型,而不需要任何公共继承或特殊等价方法。编译器将捕获不兼容的类型操作。

trait Trait1[T]
  def method1: T  // Method happens to do something safely compatible with SomeClass
}

trait Trait2[T <: SomeClass]
  def method2: T
}

class NewClass[T <: SomeClass] extends Class1[T] with Trait1[T] with Trait2[T]
于 2013-09-12T07:48:14.370 回答