Chapter 13 《Packages and Imports》

在大程序中,减少耦合是很重要的,耦合是指程序不同部分依赖其他部分的程度。低耦合能够减少局部修改对其它部分造成的影响。方法就是以模块化的风格来书写代码。本章就是利用包和引入来进行模块化风格的编程。


将代码放进包里
  • 有两种方式,

    • 1.第一种是在源码的最上方放入package语句。
    package.bobstore.navigation
    
      1. 第二种方式是类似于命名空间的方式,可以在一个文件中包含多个包的内容
    package bobsrockets {
    package navigation {
    // In package bobsrockets.navigation
    class Navigator
    package tests {
    // In package bobsrockets.navigation.tests
    class NavigatorSuite
    }
    }
    }
    

    代码按照包层次结构划分之后,编译器可知道在同一个包中的代码存在某种联系。访问同一个包的代码时,可以使用简短的,不带限定前缀的名称。

      1. 在使用命名空间方式的嵌套打包方法中,在包外可以访问到的作用域在保内也可以访问到。但是这种必须使用显示的嵌套打包。
    package bobsrockets {
    class Ship {}
    package fleets {
    class Fleet {
    // No need to say bobsrockets.Ship
    def addShip() = { new Ship }
    }
    }
    }
    

    如果每个文件只有一个包,包名在文件的顶部,那么不能访问包外的作用域。

    package bobsrockets {
    class Ship
    }
    package bobsrockets.fleets {class Fleet {
    // Doesn't compile! Ship is not in scope.
    def addShip() = { new Ship }
    }
    }
    

    是无效的。

      1. 如果嫌弃package的缩进太多,可以使用多个package子句但是不用花括号。
    package bobsrockets
    package fleets
    class Fleet {
    // No need to say bobsrockets.Ship
    def addShip() = { new Ship }
    }
    

    每个包都是顶层包__root__的成员。


引入
  • 1.可以使用import引入包和它的成员。可以出现在任何地方,可以引入任何值,甚至是一个对象的值。可以引入Object中的内容。_表示通配符,表示对所有成员的便捷引入。还可以引入包本身,例如import java.util.regex,可以方便使用regex.Pattern
    1. 引入还可以重命名用来隐藏引入的成员。
      import Fruits.{Apple => McIntosh, Orange}
      在代码中使用的时候可以使用McIntosh或者Fruits.Apple
      import Fruits{Apple => McIntosh, _}
      引入Fruits的所有成员,将Apple进行重命名
      import Fruits{Pear => _, _}
      引入除了Pear的Fruits的所有成员。其实将Pear重命名为_,其实也就是隐去了这个方法。如果要在引入语句中引入所有的成员,用_表示的时候,必须将_放在引入列表的最后。

隐式引入
    1. Scala对每个程序都隐式的添加了一些引入。
    import java.lang._ // everything in the java.lang package
    import scala._ // everything in the scala package
    import Predef._ // everything in the Predef object
    
    Predef对象定义了许多类型,方法以及隐式转换的定义。对着三个引入做了处理,后引入的会遮挡前面的。StringBuilder同时出现在lang和scala包中,但是会处理称为scala标准库中的StringBuilder。

访问修饰符
  • 访问修饰符可以作用在包、类或者对象的成员上。访问修饰符将对成员的访问限定在特定的代码区域。
    private成员:只对包含该成员定义的类或者对象可见。
    protected成员:只对包含该成员定义的类或者对象以及子类中可见。
    默认的就是public成员。公共成员对任何代码都是可见的。

限定词
  • 可以使用限定词对Scala中的访问修饰符进行增强,对成员的可见性做非常细粒度的控制,非常灵活的定义成员或者类的可见性,可以将可见性分割为特定包可见。
    private[this]:仅对当前对象可见,对象私有的,只能通过当前对象this进行访问。在别的对象内是不能够访问的。隔离了其他对象对该对象的修改。
 class C {
   private[this] val num = 123
   def +(that: C) = num + that.num // compile error
}

private[X]或者protected[X]表示上至X都可见,比如X是包名,则在这个包里是可见的。
protected[X]表示在该X中或者该类的子类中都是可见的。


可见性和伴生对象
    1. 类可以访问伴生对象的所有私有成员,对象可以访问伴生类的所有私有成员。类访问伴生对象的私有成员时,使用ObjectA.privateVal。
    1. 在伴生对象的成员中一般不使用protected进行修饰,因为伴生对象没有子类。

包对象
    1. 在包中可以放置类、特质以及孤立对象等。任何能放在类级别的定义都可以放在包级别。具体做法是将这些定义放在包对象中,每一个包都有一个包对象,在其中的定义都会被当作是这个包的成员。
    1. 可以在包对象中放入一些通用的工具方法。showFruit可以像包中的其他成员一样被引入被使用。
// In file bobsdelights/package.scala
package object bobsdelights {
def showFruit(fruit: Fruit) = {
import fruit._
println(name + "s are " + color)
}
}
// In file PrintMenu.scala
package printmenu
import bobsdelights.Fruits
import bobsdelights.showFruit

包对象会编译成为package.class的类文件,位于该包的对应目录下。包对象的源码一般放在对应的包中,名为package.scala文件中。

最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Scala与Java的关系 Scala与Java的关系是非常紧密的!! 因为Scala是基于Java虚拟机,也就是...
    灯火gg阅读 3,619评论 1赞 24
  • 前言 人生苦多,快来 Kotlin ,快速学习Kotlin! 什么是Kotlin? Kotlin 是种静态类型编程...
    任半生嚣狂阅读 26,950评论 9赞 118
  • 我不想去寻找答案,可我每次都不得不去想。也许我得不到答案,我的答案在哪里,它一直萦绕在我身边,可我不敢去认可它...
    窗台的猫王爷阅读 530评论 0赞 0
  • 美国教育家古德莱德说:“没有更好的教师就不会有更好的学校,但没有教师可以在其中学习、实践和发展自身的更好的学校,也...
    耕耘三尺有天地阅读 954评论 1赞 3
  • 難得齊聚的月會,三部的家人們都敞開心扉彼此傾訴著心聲,每個人都渴望融入團隊,有人能夠懂自己、理解自己。我的心也是滿...
    夢瑤阅读 212评论 0赞 0

友情链接更多精彩内容