在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ Scala/ 抽象類型
 初始化抽象 vals
延遲初始化(Lazy vals)
Type 成員
抽象類型
預(yù)先初始化成員的值

抽象類型

在本專題開始,我們看到“Type T”的用法,這是聲明一個(gè)抽象類型,本篇介紹這種聲明的意義和用途。和其它類型的抽象類型一樣,抽象類型定義也是定義了一個(gè)“占位符”類型,其具體定義由其子類聲明。不同的子類可以定義不同T的具體類型。 下面我們通過(guò)一個(gè)例子來(lái)說(shuō)明抽象類型的用法,假定你需要為動(dòng)物的飲食習(xí)性建模, 你可能會(huì)定義如下的數(shù)據(jù)結(jié)構(gòu):


class Food
abstract class Animal {
    def eat(food: Food)
}
然后呢可能需要實(shí)現(xiàn)兩個(gè)不同的實(shí)類對(duì)于與牛和草 Cows和Grass

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

但是這段代碼編譯不通過(guò):


<console>:13: error: class Cow needs to be abstract, since method eat in class Animal of type (food: Food)Unit is not defined
(Note that Food does not match Grass: class Grass is a subclass of class Food, but method parameter types must match exactly.)
       class Cow extends Animal {
             ^
<console>:14: error: method eat overrides nothing.
Note: the super classes of class Cow contain the following, non final members named eat:
def eat(food: Food): Unit
       override def eat(food: Grass) {}

怎么會(huì)出錯(cuò)呢,這是因?yàn)轭?Cow 中的 eat 不能重載其父類,這是因?yàn)閰?shù)類型不一致,Animal 中 food 類型為 Food,而 Cow 中類型為 Grass。 僅管有人會(huì)說(shuō) Grass 是 Food 的子類,編譯器沒(méi)有必要這么嚴(yán)格。但是如果編譯器允許這種情況存在,那么很快就出現(xiàn)新問(wèn)題了:

假定前面的編譯沒(méi)有問(wèn)題,我們?cè)诙x一個(gè)Fish類


class Fish extends Food
val bessy: Animal = new Cow
bessy eat (new Fish)

問(wèn)題來(lái)了,我們給牛喂了魚。如果前面的 Cow 可以編譯通過(guò)的話,這段代碼也是合法的,但結(jié)果卻顯然不對(duì),因此編譯器編譯不通過(guò) Cow 是有道理的。 對(duì)于這個(gè)問(wèn)題,我們可以通過(guò)抽象類型來(lái)解決,哪種動(dòng)物吃哪種食物由動(dòng)物決定:


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

當(dāng)定義新的 Animal 子類時(shí),動(dòng)物只能吃合適的食物,而 Animal 類本身不能決定那種食物合適,因此我們使用抽象類型定義。 但這個(gè)抽象類型有類型上界限制,表示 Animal 子類中使用的 SuitableFood 必須是 Food 的子類。

我們重新定義 Cow 如下:


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

你現(xiàn)在再試試喂魚給??纯矗?/p>


scala> class Fish extends Food
defined class Fish

scala> val bessy :Animal = new Cow
bessy: Animal = Cow@a0992a

scala> bessy eat (new Fish)
<console>:14: error: type mismatch;
 found   : Fish
 required: bessy.SuitableFood
              bessy eat (new Fish)
                         ^