第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 !
这里使用类型参数而不是抽象类型的区别在哪里?
答案 0 :(得分:2)
Martin Odersky在this采访中回答了这个问题。
总有两种抽象概念:参数化和抽象成员。在Java中你也有两个,但是 这取决于你抽象的东西。在Java中你有抽象 方法,但您不能将方法作为参数传递。你没有 抽象字段,但您可以将值作为参数传递。和 类似地,您没有抽象类型成员,但您可以指定一个 输入参数。所以在Java中你也有这三个,但是 你可以使用什么抽象原则有区别 什么样的东西你可以说这种区别是 相当随意。
我们在Scala中所做的是尝试更完整和正交。我们决定为这三个人制定相同的建筑原则 各种各样的成员。所以你可以有抽象的字段和价值 参数。您可以将方法(或“函数”)作为参数传递,或者 你可以抽象出来。您可以将类型指定为参数,或 你可以抽象出来。我们从概念上得到的是我们 可以用另一个来模拟一个。至少在原则上,我们可以 将各种参数化表达为面向对象的一种形式 抽象。所以在某种意义上你可以说Scala更正交 和完整的语言。
尽管如此,两者之间存在一些微妙的差异,但我无法回想起它们。
您可能还想查看this主题。