对Scala多态性的澄清

时间:2017-06-01 18:43:27

标签: scala oop polymorphism

在最近的工作表中,我遇到了一个问题,询问以下代码的输出结果:

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的子类?

稍后运行代码段时,给出的结果只是&#34; 1&#34;正在印刷。这不是我期望调用obj.m(2.3)来解决def m(x: any)的问题,实际上编译器似乎在A m中调用了class A

后面的表达式obj2.m(4)obj2.m(5.6)似乎有意义,因为4和5.6都会在def m(x: Double)的函数中落地,因此不会打印任何内容。

编译器以什么顺序遍历以查找要调用的内容?如果有人能够清除我对Scala如何处理多态性的困惑,我将非常感激,非常感谢你:)

1 个答案:

答案 0 :(得分: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]