2017-01-02 35 views
1

在這一段代碼下面我明白爲什麼我必須按順序調用asInstanctOf能夠調用bazMethod從類Baz重寫方法簽名,以避免調用.asInstanceOf客戶端代碼

class Bar[BR] 
class Baz extends Bar[Int] { 
    def bazMethod: Unit = {} 
} 

def map[A, B](args: Seq[Bar[A]])(f: Bar[A] => B): Seq[B] = args.map(f) 

//Client Code 
val bazes = Seq(new Baz) 
map(bazes)(b => b.asInstanceOf[Baz].bazMethod) 

但是什麼我想知道的是是否有方法來重寫此客戶端代碼不必使用asInstanceOf只有一個條件:我需要參考Bar[A]在方法中以某種方式提供給我。想象這是一個更復雜的方法,其中的東西需要根據A究竟是什麼來完成。

+0

爲什麼不使用繼承並在Bar中定義抽象的'bazMethod'? –

+0

@VictorMoroz在實際的代碼中,我正在對'''Bar'''實施相應的類實際上是在一些第三方庫中。我只能自由修改'''Baz'''。我也想通過類型參數來驗證解決方案的存在性,然後繼續我知道的繼承。它對我有學習價值。 – shayan

回答

2

如果你有map接受T <: Bar[_]那麼它應該工作:

scala> :pa 
// Entering paste mode (ctrl-D to finish) 

class Bar[BR] 
class Baz extends Bar[Int] { 
    def bazMethod: Unit = {} 
} 

def map[B, T <: Bar[_]](args: Seq[T])(method: T => B): Seq[B] = args.map(method) 

// Exiting paste mode, now interpreting. 

defined class Bar 
defined class Baz 
map: [B, T <: Bar[_]](args: Seq[T])(method: T => B)Seq[B] 

scala> val bazes = Seq(new Baz) 
bazes: Seq[Baz] = List([email protected]) 

scala> map(bazes)(b => b.bazMethod) 
res0: Seq[Unit] = List(()) 

否則,@碧玉-M所指出的,如果你想訪問類型參數A,你會做這樣的事情:

scala> :pa 
// Entering paste mode (ctrl-D to finish) 

class Bar[BR] 
class Baz extends Bar[Int] { 
    def bazMethod: Unit = {} 
} 

def map[B, T <: Bar[A], A](args: Seq[T with Bar[A]])(method: T => B): Seq[B] = args.map(method) 

// Exiting paste mode, now interpreting. 

defined class Bar 
defined class Baz 
map: [B, T <: Bar[A], A](args: Seq[T with Bar[A]])(method: T => B)Seq[B] 

scala> val bazes = Seq(new Baz) 
bazes: Seq[Baz] = List([email protected]) 

scala> map(bazes)(b => b.bazMethod) 
res0: Seq[Unit] = List(()) 
+0

謝謝你,這確實消除了對'''asInstanceOf'''的需求。但是我失去了對我真正需要的參數'''A'''的訪問。任何解決方案? – shayan

+0

請參閱我的編輯,您需要將類型參數添加到'Baz' –

+0

在'class Baz [Int] extends Bar [Int]'現在'Int'不再指向整數類型。它等於Baz [T]擴展Bar [T]'。 –