如果一个标识符或选择e引用了数个类的成员,则将使用引用的上下文来推断唯一的成员。使用的方法将依赖于e是否被用作一个函数。设A是e引用的成员的集合。 首先假定e作为函数出现在应用中,比如e(args)。如果在A中有且仅有一个可选成员是一个(可能是多态)方法类型,其元数与给出的参量数目匹配,则就会选定该可选成员。 否则,设Ts是通过用未定义类型来类型化每个参量所得到的类型向量。首先要确定的是可用的可选成员的集合。如果Ts中每个类型都与对应的可选成员中正式参数类型相似,且如果期望类型已定义,方法的结果类型与之兼容,则该可选项是可用的。对于一个多态方法,如果本地类型推断可以确定类型参量,则该实例化的方法是可用的,继而该多态方法也是可用的。 设B是可用的可选项的集合。如果B为空则导致错误。否则可以用以下”同样具体”和”更具体” 的定义来选出在B中最具体的可选项: 具有类型(Ts)U的参数化的方法,如果有某些类型为S的其他成员,S对于类型Ts的参量(ps)是可用的,则该方法与这些成员同样具体。 具有类型[a1 >: L1 <: U1,...,an >: Ln <: Un]T的多态方法,如果有某些类型为S其他成员,如果假定对于i=1,...,n,每个ai都是一个抽象类型命名,其边界在Li之上且在Ui之下,有T和S同样具体,则该方法和这些成员同样具体。 具有其他类型的成员总是与一个参数化的方法或一个多态方法同样具体。 给定具有类型T和U的两个没有参数化也不是多态方法类型的成员,类型为T的成员与类型为U的成员同样具体的条件是T的双重存在与U的双重存在相似。这里多态类型[a1 >: L1 <: U1,...,an >: Ln <: Un]T的双重存在是T forSome { type a1 >: L1 <: U1,...,type an >: Ln <: Un}。其他类型的双重存在是类型自身。 如果A与B同样具体,同时要么B与A不同样具体,要么A在B的一个子类中定义,则A比B更具体。 如果B中没有可选项比B中其他可选项更具体则将导致错误。 下面假定e以函数的形式在类型应用中出现,比如e[targs]。那么我们将选择A中所有的与targs中的类型参量具有同样数目的参数类型的可选项。如果没有该类可选项将导致错误。如果有多个这样的可选项,则将对整个表达式e[targs]重新应用重载解析。 最后我们假定e没有在应用或类型应用中做为函数出现。如果给出了期望类型,设B是A中与其兼的该类可选项的集合。否则,设B为A。在此情况下我们在B的所有可选项中选择最具体的可选项。如果B中没有可选项比B中其他所有的可选项更具体则将导致错误。 在所有情况下,如果最具体的可选项定义在类C中,且有另外一个可应用的可选项定义在C的子类中,则将导致错误。 示例6.25.1 考虑以下定义: class A extends B {} def f(x: B, y: B) = ... def f(x: A, y: B) = ... val a: A val b: B 则应用f(b, b)指向f的第一个定义,应用f(a, a)指向第二个。假设我们添加第三个重载定义 def f(x: B, y: A) = ... 则应用f(a, a)将因模糊定义而被拒绝,因为不存在更具体的可应用签名。 |
更多精彩内容请关注:http://bbs.superwu.cn
关注超人学院微信二维码:
关注超人学院java免费学习交流群:
时间: 2024-11-03 03:39:46