通过前面二帖对路径依赖的分析可知,不管是内部类还是内部抽象类型,当出现路径依赖的时候,
都必须要与对应的名称即变量紧密联系在一起。但有时候,希望只要是同一种类型的都可以接受,
不需要这么严格的路径依赖要求,这就涉及到类型投影概念(type projection)。
比如说有a1.B类型,a2.B类型,根据路径依赖确实是不同的类型,但B所在的外部类却都是相同的,
即类A,也就是说A#B这种语法形式。所以针对前面二帖用类型投影来做的话:
class Outer {
private val x = 1
class Inner {
private val y = x + 5
}
def method(c:Outer#Inner): Unit = {
println("arg c is " + c.toString)
}
}
object PathDependTest {
def main(args: Array[String]): Unit = {
val outer1 = new Outer
val inner1 = new outer1.Inner
// val inner1 = new Outer.Inner //错误声明 new 不能是Outer.Inner,只能是outer1.Inner
//还可以显示声明类型
//val inner1uter1.Inner = new outer1.Inner //上面错误声明以及本句的显示声明类型outer1.Inner就已经表明:与路径名称有关
val outer2 = new Outer
val inner2 = new outer2.Inner
//如果将outer2.Inner类型赋值给outer1.Inner类型,结果会如何呢?
// val o1i uter1.Inner = new outer2.Inner //结果IDEA提示:类型不匹配
//上句错误“基本上“可以给出结论:路径依赖的是与名称有关,与类型或引用的实例无关(因为实例都是同一个类型)
val outer3 = new Outer
val outer4 = outer3
val inner3 = new outer3.Inner
// val inner4uter4.Inner = inner3 //outer4和outer3其实都是引用同一个对象,但两者的内部类不能互相赋值引用
// val inner4uter4.Inner = new outer3.Inner //new一个outer3的内部类也不能互相赋值引用
// 上面二句都提示类型错误,彻底说明:路径依赖是与名称相关,与引用的实例即类型无关
outer3.method(inner3)
outer3.method(new outer4.Inner) //都是outer3,但接收的却是不同对象的内部类
}
}
显示如下:
arg c is com.joe.stu.Outer$Inner@221af3c0
arg c is com.joe.stu.Outer$Inner@b7f23d9