2012-04-17 57 views
6

如何強制base方法在被子類重寫時接受相同的特定子類實例?用子類參數重寫子類方法?

即:

abstract class Animal { 
    def mateWith(that: Animal) 
} 

class Cow extends Animal { 
    override def mateWith...? 
} 

從邏輯上講,應該Cow只能夠mateWith另一個Cow。但是,如果我做override def mateWith(that: Cow),這實際上並沒有覆蓋基類方法(我希望它,因爲我想強制它的存在在子類中)。

我可以檢查以確保其他實例的類型爲Cow,如果不是,則拋出異常 - 這是我的最佳選擇嗎?如果我有更多的動物呢?我將不得不重複拋出異常的代碼。

回答

11
abstract class Animal[T <: Animal[T]] { 
    def mateWith(that: T) 
} 

class Cow extends Animal[Cow] { 
    override def mateWith(that: Cow) { println("cow") } 
} 

class Dog extends Animal[Dog] { 
    override def mateWith(that: Dog) { println("dog") } 
} 

而且使用這樣的:

scala> (new Cow).mateWith(new Cow) 
cow 

scala> (new Cow).mateWith(new Dog) 
<console>:17: error: type mismatch; 
found : Dog 
required: Cow 
       (new Cow).mateWith(new Dog) 
           ^

不需要異常拋出代碼;類型系統會在編譯時爲您處理它!

+1

甜美的交易,斯卡拉的方便! – 2012-04-17 21:27:53

+1

我不太確定「方便」,但表現力很強。 – 2013-02-07 04:32:42

+1

以爲我會重溫這個 - 這被稱爲[f-bound-polymorphism](https://twitter.github.io/scala_school/advanced-types.html#fbounded)。 – 2015-10-14 21:10:22