抽象类型与类型参数 - 区别在哪里?

时间:2012-06-29 18:27:51

标签: scala type-parameter abstract-type

  

可能重复:
  Scala: Abstract Types vs Generics

第20.6章'抽象类型'在Scala编程'编程解释了抽象类型的使用以及以下结果代码结尾的示例:

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 !

这里使用类型参数而不是抽象类型的区别在哪里?

1 个答案:

答案 0 :(得分:2)

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

  

总有两种抽象概念:参数化和抽象成员。在Java中你也有两个,但是   这取决于你抽象的东西。在Java中你有抽象   方法,但您不能将方法作为参数传递。你没有   抽象字段,但您可以将值作为参数传递。和   类似地,您没有抽象类型成员,但您可以指定一个   输入参数。所以在Java中你也有这三个,但是   你可以使用什么抽象原则有区别   什么样的东西你可以说这种区别是   相当随意。

     

我们在Scala中所做的是尝试更完整和正交。我们决定为这三个人制定相同的建筑原则   各种各样的成员。所以你可以有抽象的字段和价值   参数。您可以将方法(或“函数”)作为参数传递,或者   你可以抽象出来。您可以将类型指定为参数,或   你可以抽象出来。我们从概念上得到的是我们   可以用另一个来模拟一个。至少在原则上,我们可以   将各种参数化表达为面向对象的一种形式   抽象。所以在某种意义上你可以说Scala更正交   和完整的语言。

尽管如此,两者之间存在一些微妙的差异,但我无法回想起它们。

您可能还想查看this主题。