【问题标题】:Clarification over Scala polymorphism对 Scala 多态性的澄清
【发布时间】:2017-06-01 18:43:27
【问题描述】:

在最近的工作表中,有人问我以下代码的输出是什么:

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

稍后运行代码 sn-p 时,给出的结果只是打印了“1”。这不是我预期对obj.m(2.3) 的调用在def m(x: any) 处解析的结果,实际上编译器似乎上升到A 并在class A 中调用m

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

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

【问题讨论】:

    标签: scala oop polymorphism


    【解决方案1】:

    当您执行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]
    

    【讨论】:

    • 啊,非常感谢。现在这很有意义 - 这是一个多么狡猾的问题:)
    • 哦,还有一件事——在这种情况下,函数参数中的 Any 是像“T”一样起作用还是指的是实际的类型 Any?我当时接受不了,因为有时间限制
    • 它的作用类似于T。实际类型 Any 被遮蔽。
    猜你喜欢
    • 2015-01-31
    • 2016-07-19
    • 1970-01-01
    • 2021-03-29
    • 2016-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-05
    相关资源
    最近更新 更多