はじめに
先日、「アクセス修飾子まとめ~スマホアプリ開発編(Java/Kotlin/Objective-C/Swift/C#/F#)」と題してスマホアプリで使う言語のアクセス修飾子比較をまとめましたが、今回は「JVM言語」をテーマにアクセス修飾子をまとめたいと思います。
##JVM言語とは
JVM(Java Virtual Machine)上で動く言語で、Javaのほかに多数のJava代替言語が存在します。今回はその中でもメジャーなGroovy、Scala、Kotlinを取り上げ、Javaとともに比較表にまとめます。
比較表
アクセス修飾子 | Java | Groovy | Scala | Kotlin |
---|---|---|---|---|
public | どこからでもアクセス可能 | どこからでもアクセス可能 | どこからでもアクセス可能 | どこからでもアクセス可能 |
protected | 同一パッケージ内のクラス+派生クラスからアクセス可能 | どこからでもアクセス可能 | 同一クラス+派生クラスからアクセス可能 | 継承した同一パッケージ内のクラス+派生クラスからアクセス可能 |
internal | (存在しない) | (存在しない) | (存在しない) | 同一モジュール内でアクセス可能 |
private | 同一スコープ内でアクセス可能 ※内部クラスのprivate変数も参照可 |
どこからでもアクセス可能 ※ただし派生クラスからsuper.*でアクセスすることはできない |
同一スコープ内でアクセス可能 | 同一スコープ内でアクセス可能 |
protected[パッケージ名] | (存在しない) | (存在しない) | 指定したパッケージ内のクラス+派生クラスからアクセス可能 ※所属するパッケージのみ指定化(途中の階層も可) |
(存在しない) |
private[パッケージ名] | (存在しない) | (存在しない) | 指定したパッケージ内でアクセス可能 ※所属するパッケージのみ指定化(途中の階層も可) |
(存在しない) |
protected[クラス名] | (存在しない) | (存在しない) | 自身または指定したクラス+派生クラスからアクセス可能 ※自身の外側のクラスのみ指定可 |
(存在しない) |
private[クラス名] | (存在しない) | (存在しない) | 自身または指定したクラスからアクセス可能 ※自身の外側のクラスのみ指定可 |
(存在しない) |
protected[this] | (存在しない) | (存在しない) | 自インスタンス+派生クラスからアクセス可能 | (存在しない) |
private[this] | (存在しない) | (存在しない) | 自インスタンスからのみアクセス可能 | (存在しない) |
指定しない | 同一パッケージ内でアクセス可能 | publicと同じ | publicと同じ | publicと同じ |
GroovyはJavaと互換性があるため、Java同様のアクセス修飾子が使えますが、それらはうまく機能せず、なんとすべてどこからでもアクセスできてしまいます(一応省略時publicになるというのは仕様通り)。この動作はバグとして管理されていますが、すべて修正されるのはまだ先のようです(本稿作成にあたりGroovy2.4.12で検証)。
Scalaでは限定子というものがあり、きめ細かいアクセスコントロールができるのが特徴ですね。
Java以外の代替言語は、何も指定しなかったとき「public」になる動きで共通です。
「アクセスコントロールを行うキーワードを書かない」
⇒「アクセスコントロールしない」
⇒「どこからでもアクセス可能」
と考えられるので、直感的でわかりやすいと思います。
参考
[GROOVY-3010] fix private field visibility - ASF JIRA
[GROOVY-7246] Access modifiers behave differently in Groovy when compared to Java. - ASF JIRA
Scalaクラスメモ(Hishidama's Scala class Memo)
クラスメンバーのアクセス修飾子 | hydroculのメモ
はじめてのKotlin。Javaと比較してみた