zoukankan      html  css  js  c++  java
  • Scala for the Impatients---(7)Packages and Imports

    Packages

    A package can be defined in multiple files. For example

    //Employee.scala
    package com {
        package horstmann {
            package impatient {
                class Employee
                ...
    }
        }
            }  

    and

    //Manager.scala
    package com {
        package horstmann {
            package impatient {
                class Manager
                ...
    }
    }
    }    

    Multiple packages can be in a single file. For example

    \Employee.scala
    package
    com { package horstmann { package impatient { class Employee ... } } } package org { package bigjava { class Counter ... } }

    Note: There is no enforced relationship between the directory of the source file and the package. You don’t have to put Employee.scala and Manager.scala into a com/horstmann/impatient directory.

    Scope Rules

    (1)Let's look at this example

    package com {
        package horstmann {
            object Utils {
                def percentOf(value: Double, rate: Double) = value * rate / 100
                ...
            }
            package impatient {
                class Employee {
                    ...
                    def giveRaise(rate: scala.Double) {
                        salary += Utils.percentOf(salary, rate)
                     }
                }
            }
        }
    }

    Note the Utils.percentOf qualifier. Here the class Employee is in the impatient package which, combined with Utils, is in the horstmann package. So everything in the parent package is in scope.

    (2)the scala package is always imported. For example

    package com {
    package horstmann {
    package impatient {
    class Manager {
    val subordinates = new collection.mutable.ArrayBuffer[Employee]
    ...
    }
    }
    }
    }

    Therefore, the collection package is actually scala.collection.mutable.ArrayBuffer. But this omitting can cause a problem. Suppose that we, in a new file, add a subpackage collection in the parent package horstmann, then the tree structure is like:

                                  |----impatient--->Manager

    com---horstmann---

                                  |----collection---child-->Boy

    Where collection.mutable.ArrayBuffer[Employee] in the class Manager will never compile! Because it will not look for scala.collection, but only look for com.horstmann.collection.mutable, there is no such mutable package, only a package named child. To solve this conflict, Scala introduces chained package clauses.

    Chained Package Clauses

    A package clause can contain a “chain,” or path segment, for example:

    package com.horstmann.impatient {
    // Members of com and com.horstmann are not visible here
    package people {
    class Person
    ...
    }
    }

    Such a clause limits the visible members. Now a com.horstmann.collection package would no longer be accessible as collection.

    Top-of-File Notation

    Instead of the nested notation that we have used up to now, you can have package clauses at the top of the file, without braces. For example

    package com.horstmann.impatient
    package people
    class Person
    ...

    This is equivalent to

    package com.horstmann.impatient {
    package people {
    class Person
    ...
    // Until the end of the file
    }
    }

    Note that in the example above, everything in the file belongs to the package com.horstmann.impatient.people , but the package com.horstmann.impatient has also been opened up so you can refer to its contents.

    Package Objects

    A package can contain classes, objects, and traits, but not the definitions of functions or variables. That’s an unfortunate  limitation of the Java virtual machine. It would make more sense to add utility functions or constants to a package than to some Utils object. Package objects address this limitation. 

    Every package can have one package object. You define it in the parent package, and it has the same name as the child package. For example,

    package com.horstmann.impatient
        package object people {
            val defaultName = "John Q. Public"
        }
        package people {
            class Person {
                var name = defaultName // A constant from the package
    ... }
    } ... }

    Elsewhere it is accessible as com.horstmann.impatient.people.defaultName. Behind the scenes, the package object gets compiled into a JVM class with static methods and fields(here it is defaultName).  It is a good idea to use the same naming scheme for source files. Put the package object into a file com/horstmann/impatient/people/package.scala . That way, anyone who wants to add functions or variables to a package can find the package object easily.

    Package Visibility

    In Java, a class member that isn't declared as public/private/protected is visible in the package containing the class.

    In Scala, you can achieve this with qualifiers. The following method is visible in its own package:

    package com.horstmann.impatient.people
    class Person {
    private[people] def description = "A person with name " + name
    ...
    }

    You can extend the visibility to an enclosing package:

    private[impatient] def description = "A person with name " + name

    Imports

    There is a point that Java doesn't have is that Scala can import all members of a class or object. Like

    import java.awt.Color._
    val c1 = RED // Color.RED
    val c2 = decode("#ff0000") // Color.decode

    Note that imports can be anywhere. The scope of the import statement extends until the end of the enclosing block. For example,

    class Manager {
    import scala.collection.mutable._
    val subordinates = new ArrayBuffer[Employee]
    ...
    }

    By putting the imports where they are needed, you can greatly reduce the potential for conflicts.

    Renaming and Hiding Members

    If you want to import a few members from a package, use a selector like this:

    import java.awt.{Color, Font}

    The selector syntax lets you rename members:

    import java.util.{HashMap => JavaHashMap}
    import scala.collection.mutable._

    Now JavaHashMap is a java.util.HashMap and plain HashMap is a scala.collection.mutable.HashMap .

    The selector HashMap => _ hides a member instead of renaming it. This is only useful if you import others:

    import java.util.{HashMap => _, _}
    import scala.collection.mutable._

    Now HashMap unambiguously refers to scala.collection.mutable.HashMap since java.util.HashMap is hidden.

    Implicit Imports

    Every Scala program implicitly starts with

    import java.lang._
    import scala._
    import Predef._
  • 相关阅读:
    [荐]推荐一个shell学习的网站
    [转]linux远程登入不需要密码
    [转] eclipce使用vim 开启装逼模式
    Linux 下查找指令
    nmon 工具的使用
    LaTeX 符号大全
    vim 粘贴复制操作
    linux命令模式下如何切换首行和尾行
    fish 与oh-my-fish 的安装
    vim 粘贴复制操作
  • 原文地址:https://www.cnblogs.com/chaseblack/p/5876551.html
Copyright © 2011-2022 走看看