2013-07-16 41 views
4

在C#中,你可以明確地實現接口。明確實現的方法只能通過一個接口作爲靜態類型的變量來調用。這樣可以避免名稱/返回類型衝突,並根據this的靜態類型提供相同方法的不同實現。Scala是否有類似於C#的顯式接口實現?

例如:

interface IFoo 
{ 
    int DoSomething(); 
} 

interface IBar 
{ 
    string DoSomething(); 
} 

class Impl : IFoo, IBar 
{ 
    int IFoo.DoSomething() { /* Implementation for IFoo */ } 
    string IBar.DoSomething() { /* A different implementation for IBar */ } 
    public void DoSomething() { /* Yet another implementation for Impl */ } 
} 

你將如何在斯卡拉處理這種情況:

trait Foo { 
    def doSomething(): Int 
} 

trait Bar { 
    def doSomething(): String 
} 

class Impl extends Foo with Bar { 
    /* only one "doSomething()" visible here (that of Bar?) */ 
    /* what now... ? */ 
} 
+0

您可以使用泛型T?不是100%你得到什麼,但似乎你可以使用它。你試圖根據相同的簽名方法返回不同的類型?例如:你可以有T DoSomething (); –

回答

3

如果你只是想讓你的類遵循兩個單獨的不兼容的接口,那麼你就必須編寫包裝器。例如,

implicit case class ImplAsFoo(impl: Impl) extends Foo { 
    def asFoo = this 
    def doSomething: Int = 5 
} 

現在你可以

impl.asFoo 

在使用現場切換到富包裝。

在某些情況下,雖然,它可能是更自然的使用類型類模式,而不是提供可插拔的功能:

trait IFoo[A] { def doSomething: Int } 
trait IBar[A] { def doSomething: String } 

// These need to be companions so :paste if you're using REPL 
class Impl { def doSomething { println("Hey!") } } 
object Impl { 
    implicit object FooImpl extends IFoo[Impl] { def doSomething = 5 } 
    implicit object BarImpl extends IBar[Impl] { def doSomething = "salmon" } 
} 

def needsFoo[A <: Impl: IFoo](a: A) = implicitly[IFoo[Impl]].doSomething 

scala> needsFoo(new Impl) 
res1: Int = 5 

scala> (new Impl).doSomething 
Hey! 

這不是正是一樣,但是這也可以處理不同的問題沒有命名方案的實現會讓你失望。 (如果你需要doSomethingimpl對象,你把它作爲在處理這種情況下,implicit object的參數。)

如果你已經有特點,那當然這不會幫助你。但是當你從頭開始設計時,而不是用一堆不兼容的方法來表達特徵時,你可能會嘗試輸入類。

最後,如果你不能有一堆的非類型化的東西混在一起外面幫你需要選擇Foo S,你必須創造更周密的計劃,像這樣:

trait CanBeFoo { def asFoo: Foo } 
trait Foo { def doSomething: Int } 

// :paste these two together 
class Impl extends CanBeFoo { 
    def doSomething { println("Ho!") } 
    def asFoo = ImplAsFoo(this) 
} 
case class ImplAsFoo(impl: Impl) extends Foo { 
    def doSomething = 6 
} 

val myList = List("salmon", new Impl, new Foo { def doSomething = 4 }) 
def doIt(f: Foo) { println(f.doSomething) } 
myList.foreach { 
    case f: Foo => doIt(f) 
    case cf: CanBeFoo => doIt(cf.asFoo) 
    case _ => println("nuh-uh") 
} 

// Produces 
// nuh-uh 
// 6 
// 4 

你可能會喜歡的中間圖:

myList.map{ case cf: CanBeFoo => cf.asFoo; case x => x }.foreach{ 
    case f: Foo => println(f.doSomething) 
    case _ => println("nuh-uh") 
} 
2

沒有,這些都是嚴格不兼容的基本類型。當一個類擴展一個特徵時,它將該特徵作爲其類型標識的一部分。它不能有任何相互不兼容的類型身份,就像你寫這些特性的任何類一樣。

相關問題