Java & Groovy & Scala & Kotlin - 22.包與訪問權限

Overview

本章主要介紹各語言中的包和訪問權限控制。

Java 篇

創建包

  • Java 使用關鍵字 package 來聲明一個包。
  • 包名中使用 . 作為路徑分隔符,且包路徑必須與源文件路徑相同。
  • 包只能聲明在源文件開頭。

例:

package a.b;
class B {}

導入包

  • Java 使用關鍵字 import 導入包。
  • 可以使用通配符 *,導入一個包下的所有類。
  • 如果一個類中都是靜態成員的話,可以使用靜態導入 static import 導入該類的所有靜態成員,這樣使用時就不用指定類名了。
  • 導入語句只能聲明在源文件開頭,包聲明之后。

導入指定的類

import a.b.B;

導入指定包下的所有類

import a.b.*;

靜態導入

static import a.b.B.*;

package-info

Java 中每個包都可以聲明一個名為 package-info.java 的源文件。該源文件主要在生成文檔時用于描述當前包的功能和作用,有時也可以用于定義僅在包中共享的靜態變量和靜態方法。

訪問權限

Java 中訪問權限分為四種:

  • public
    • 適用于類,屬性,方法
    • public 表示總是可見。如果用于修飾類,則一個源文件中只能有一個類聲明為 public。
  • private
    • 適用于內部類,屬性,方法
    • private 表示只在聲明范圍內可見,所以修飾類時只能修飾內部類。
  • friendly
    • 適用于類,屬性,方法
    • 默認訪問控制權限,又稱為 default,在同包中可見,使用時不用真的添加 friendlydefault 關鍵字。
  • protected
    • 適用于類,屬性,方法
    • protected 等于 friendly + 子類可見。

注意: Java 并沒有父包和子包的概念,即 a.b.ca.b 沒有任何關系,也不存在訪問控制權限的傳遞,所以 a.b.c 中定義的類無法訪問 a.b 中的類定義的私有成員。

Groovy 篇

創建包與導入包均與 Java 相同。

訪問權限

Groovy 中訪問權限分為四種:

  • public
    • 適用于類,屬性,方法
    • 默認訪問控制權限,可以省略,表示總是可見。和 Java 不一樣,Groovy 中一個源文件中可以有多個類聲明為 public。
  • private
    • 適用于內部類,屬性,方法
    • private 表示只在聲明范圍內可見,所以修飾類時只能修飾內部類。
  • protected
    • 適用于類,屬性,方法
    • protected 等于 friendly + 子類可見。
  • package
    • 適用于類,屬性,方法

    • 類似 Java 的默認權限,使用方式較為復雜,并不推薦。

      package 權限的例子

      定義一個包含 package 權限方法的類

      package a.b
      class B {
        def foo() {}
        @PackageScope def packageFoo() {}
      }
      

      使用以上類

      package a
      class A {
      
        @CompileStatic
        def foo() {
          def b = new B()(
          b.foo()
          b.packageFoo()
        }
      }
      

      調用包含 package 權限的類的方法必須被聲明為 @CompileStatic,否則 package 權限會被忽略。

Groovy 中也沒有父包和子包的概念。

Scala 篇

創建包

  • Scala 也使用關鍵字 package 來聲明一個包。
  • 包名中使用 . 作為路徑分隔符,和 Java 不同包路徑無須與源文件路徑相同。
  • 包可以聲明在任意位置。

使用塊聲明包

package A {
  package B {
    class B {
    }
  }
}

此時 AA.B 包的成員對 class C 直接可見。

使用串聯式包名

package A.B.C {
  class C {
  }
}

此時 AA.B 包的成員對 class C 并不直接可見。

使用頂部標記聲明在源文件開頭,對整個源文件有效

package A.B
package C

等同于

package A {
  package B {
    package C {}
  }
}

導入包

  • Scala 使用關鍵字 import 導入包。
  • 可以使用通配符 _,導入一個包下的所有類
  • 可以使用選取器 {} 導入一個包下的某些類或者指定別名
  • 導入語句可以放在任意位置,包括方法內部。

導入指定的類

import a.b.B

導入指定包下的所有類

import a.b._

使用選取器導入指定的類

import java.awt.{Color,Font}

使用選取器重命名選取的類

import java.util.{HashMap=>JavaHashMap}

包對象

  • 包對象用于組織包內可見的常量和方法,而不用具體包含在某個 utils 對象中,通常這是更好的做法。
  • 每個包都可以包含一個包對象
  • 包對象會被編譯為對應包內的 package.class 類,所以通常做法是在對應包內建立一個名為 package.scala 的類來管理包對象。
package object Constants {
  val VERSION = "0.0.1"
}

訪問權限

Scala 中 的訪問權限比較復雜

  • public
    • 適用于類,屬性,方法
    • 默認訪問控制符,總是可見。一個源文件中可以包含多個 public 的類。
  • private
    • 適用于內部類,屬性,方法
    • private 表示只在當前聲明范圍內可見,所以修飾類時只能修飾內部類。與 Java 最大的不同是外部類是無法調用內部類的 private 成員的。
  • protected
    • 適用于類,屬性,方法
    • protected 表示僅子類可見,與 Java 完全不同。
  • scope
    • Scala 中可以結合以上的訪問控制符和scope符號 [] 來自定義訪問控制權限。

      自定義包作用域

      package A.B.C {
        class C {
          private[C] def desc = "desc"        //同包
          private[B] def impress = "impress"  //上一級包
        }
      }
      

Scala 包支持嵌套,即下層可以直接訪問上層作用域的成員。但是如果使用了串聯式包名,則必須手動引入對應的包才能正常使用。而在 Java 中不同包名沒有任何直接關系。

Kotlin 篇

創建包

與 Java 相同。

導入包

與 Java 相同。但是 Kotlin 在導入包時可以指定別名。

指定別名

import foo.bar as b

val b = b()
b.bar()

默認包

如果一個 kotlin 源文件中沒有任何包聲明,則其當中的代碼均屬于默認包,導入時包名即為函數名

fun hello() {
    println("hello, Default Package")
}

import hello
hello()

訪問權限

Kotlin 中訪問權限分為四種:

  • public
    • 適用于類,屬性,方法
    • public 表示總是可見。
  • private
    • 適用于類,屬性,方法
    • private 表示在聲明范圍及同模塊的子作用域內可見。
  • internal
    • 適用于類,屬性,方法
    • 默認作用域,同模塊中可見。
  • protected
    • 適用于類,屬性,方法
    • protected 表示 private + 子類可見,與 Java 完全不同。

模塊是 Kotlin 的一個特殊的概念,表示的是一個單獨的編譯單元,概念類似Maven中的模塊。

Summary

  • Scala 的包聲明與其它語言都不一樣
  • Scala 和 Kotlin 導入包時支持指定別名
  • Scala 和 Kotlin 的訪問權限與另兩種有很大區別

文章源碼見 https://github.com/SidneyXu/JGSK 倉庫的 _22_package 小節

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 前言 人生苦多,快來 Kotlin ,快速學習Kotlin! 什么是Kotlin? Kotlin 是種靜態類型編程...
    任半生囂狂閱讀 26,276評論 9 118
  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,923評論 18 139
  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,765評論 18 399
  • 更多文章http://blog.csdn.net/qq_29284809當我們在Xcode中使用CocoaPods...
    Frank_chun閱讀 2,543評論 1 3
  • 靜坐、慢走帶給我們無法想象到的力量,內在的放松與強大以及當下的生命帶給自己的一切。除了這兩種方式,與自己生命聯結的...
    瘋玩閱讀 170評論 3 1