2017-06-01 64 views
2

在最近的一個工作表中我提出了與問題,問什麼會是下面的代碼的輸出:澄清了斯卡拉多態性

class A { def m(x:Double) = x+x } 
class B[Any] extends A{ def m(x: Any) = print(x) } 
class C[Any] { def m (x:Double) = x+x; def m (x: Any) = print(x) } 
val obj1 = new B[Int]; val obj2 = new C[Any] 
obj1.m(1); obj1.m(2.3); obj2.m(4); obj2.m(5.6) 

我爲有在廣場的具體類型是什麼很困惑類名後的括號意味着(即class B[Any])。後面的表達式val obj1 = new B[Int]是否有效,因爲Int <: Any,Int是Any的子類?

當稍後運行代碼片段時,給出的結果只是打印出「1」。這不是我所期望的呼叫obj.m(2.3)def m(x: any)解決,在那裏它似乎在實際上編譯器上升到A,並在class Am

後面的表達式obj2.m(4)obj2.m(5.6)似乎是有意義的,因爲4和5.6將落入函數def m(x: Double),因此不打印任何東西。

編譯器遍歷的順序是什麼?如果有人能夠澄清我對Scala處理多態性的困惑,非常感謝,非常感謝你:)

回答

5

當你做class B[Any]時,你定義了一個類型參數爲Any的類。不要將類型參數名稱與實際類Any混淆。你只是遮住了它的名字。

你可以很細做:

class B[Int] 
val obj = new B[String] 

您可能會看到爲什麼它是不好的做法,名稱類型參數的實際類型之後。通常,人們使用單個字母名稱作爲其類型參數,如下所示:

class B[T] // I just changed the name of the type parameter from "Int" to "T". 
val obj = new B[String] 
+0

啊,非常感謝。這使得現在有很多意義 - 這是一個狡猾的問題:) – CowNorris

+0

@ user2938375請接受答案。 – marstran

+0

噢,還有一件事情 - 在這種情況下,函數參數裏面的Any的行爲就像「T」還是它指的是實際的類型Any? 我無法接受它,因爲有時間限制 – CowNorris