2017-06-01 66 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