在最近的工作表中,我遇到了一个问题,询问以下代码的输出结果:
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如何处理多态性的困惑,我将非常感激,非常感谢你:)
答案 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]