scala 包和引入和this.type

2020-08-27  本文已影响0人  wong11

1.scala包

scala的包和Java中的包的目的是相同的:管理大型程序中的名称。
要增加条目到包中,可以将其包含在包语句里面,如:

package org{
    package cai{
       package test{
           class MyClass
            // ......
       }
   }
}

MyClass就可以在任何地方以org.cai.test.MyClass被访问。

**源文件的目录和包之间并没有强制的关联关系,并不需要将MyClass.scala放在org/cai/test目录下面。

**可以在一个.scala文件中定义多个包的内容,如:

//包org.cai.test
package org{
    package cai{
       package test{
           class MyClass1
            // ......
       }
   }
}
//包org.yong.test
package org{
    package yong{
       package test{
           class MyClass2
             //......
       }
   }
}

2.包的作用域

scala的包和其它作用域一样支持嵌套。可以在程序中访问上层作用域中的名称。
有时候包的引入会发生冲突,这个时候我们可以通过绝对包名进行引入:
绝对包名以“root”开始。

val test = new _root_.scala.collection.mutable.ArrayBuffer[claaName]

3.串联式包语句
包语句可以包含一个串(路径区段),这样的包语法限定了可见的成员。

package org.cai.test{
    //org和org.cai的成员在这里不可见
    package pack1{
       class MyClass
        //......
   }
}

4.文件顶部标记法

和Java类似,在源文件顶部声明包。
如:

package org.cai.test
package yong
class MyClass
//......
//这等同于
package org{
    package cai{
       package test{
           package yong{
              class MyClass1
               // ......
           }
       }
   }
}

注意:在上例子中,文件所有的内容都属于org.cai.test.yong包,但是org.cai.test包的内容是可见的,可以被直接引用。

5.包对象

包可以包含类、对象和特质,但是不能包含函数或变量的定义。这是Java虚拟机的局限。

每一个包都可以有一个包对象,需要在父包中定义它,且名称与子包一样。
例如:

package org.cai.test
 
package object people{
  val defaultName = "cy"
}
 
package people{
  class Person{
    var name = defaultName //从包对象拿到常量
  }
  //......
}

defaultName不需要加限定词,因为它位于同一个包内。在其它地方,这个常量可以用org.cai.test.people.defaultName来访问到。包对象会被编译成带有静态方法和字段的JVM类,名为package.class,位于相应的包下。

6.this.type

 class A {def method1: A = this }
 class B extends A (def method2: B = this}
 val b = new B

如果调用b.method2.method1是可以的,但是如果想调用b.method1.method2就不行了。因为method1返回的是A类型的。
scala中解决这个问题的办法就是this.type,统一使用this.type

class A { def method1: this.type = this }
class B extends A { def method2: this.type = this }
val b = new B
上一篇 下一篇

猜你喜欢

热点阅读