2

可能重复:
Scala:抽象类型与泛型

“Scala 编程”的第 20.6 章“抽象类型”解释了抽象类型的使用,并带有一个以以下结果代码结尾的示例:

class Food
abstract class Animal {
  type SuitableFood <: Food
  def eat(food: SuitableFood)
}

class Grass extends Food
class Cow extends Animal {
  type SuitableFood = Grass
  override def eat(food: Grass) {}
}

有了这些定义,对象Cow不能吃鱼:

class Fish extends Food
val bessy: Animal = new Cow
bessy eat (new Fish) // Error, type mismatch

在阅读了这个关于使用抽象类型的好例子之后,我想知道,为什么我们不只使用类型参数呢?

class Food
abstract class Animal[T <: Food] { 
  def eat(food: T)
}

class Grass extends Food
class Cow extends Animal[Grass] {
  override def eat(food: Grass){}
}

class Fish extends Food
val bessy: Animal[Grass] = new Cow
bessy eat (new Fish) // Also ends in a type mismatch error !

在这里使用类型参数而不是抽象类型有什么区别?

4

1 回答 1

2

Martin Odersky 在这次采访中回答了这个问题。

一直有两个抽象概念:参数化和抽象成员。在 Java 中,你也有两者,但这取决于你抽象的内容。在 Java 中,您有抽象方法,但不能将方法作为参数传递。您没有抽象字段,但可以将值作为参数传递。同样,您没有抽象类型成员,但您可以将类型指定为参数。所以在Java中你也有这三个,但是对于你可以使用什么样的抽象原则是有区别的。你可以争辩说这种区别是相当武断的。

我们在 Scala 中所做的就是尝试变得更加完整和正交。我们决定对所有三种成员都采用相同的构造原则。因此,您可以拥有抽象字段以及值参数。您可以将方法(或“函数”)作为参数传递,也可以对它们进行抽象。您可以将类型指定为参数,也可以对它们进行抽象。我们从概念上得到的是,我们可以根据另一个建模一个。至少在原则上,我们可以将每一种参数化表示为一种面向对象的抽象形式。所以在某种意义上你可以说 Scala 是一种更加正交和完整的语言。

也就是说,两者之间存在一些细微的差异,但我想不起来它们。

您可能还想看看这个线程。

于 2012-06-29T19:31:45.503 回答