Kotlinの可視性修飾子

Kotlinの可視性修飾子

1. 前書き

Kotlinプログラミング言語は、Java仮想マシン(JVM)上に構築されています。 そのため、可視性修飾子を含む、JVMが課すすべてのルールに従う必要があります。

ただし、コンパイラーとコードの構造に関して、言語がこれらの修飾子を実装する方法には微妙なニュアンスがあります。 この記事では、この点でJavaとKotlinの類似点と相違点をいくつか示します。

2. 可視性修飾子

可視性修飾子は、コードの他の要素が変更中の要素にアクセスできるかどうかを判断するために使用されます。 これらは、スコープのさまざまなレベルで、コード内のいくつかの異なる要素に適用されます。 これらのルールの適用方法は、これらのさまざまな使用法の間でわずかに異なる場合があり、最初は混乱する可能性があります。

2.1. パブリックビジビリティ

最も明白な修飾子はpublicです。 これはおそらく言語全体で最も頻繁に使用され、変更される要素を誰が見ることができるかについて追加の制限がないことを意味します。

Unlike Java, in Kotlin there is almost never any need to declare anything as public –別の修飾子を宣言しない場合に使用されるデフォルトの修飾子です。 これ以外は、Javaでの動作と同じようにKotlinで動作します。

public修飾子を最上位の要素(外部クラス、またはパッケージ内で直接宣言された関数または変数)に適用すると、他のコードからアクセスできます。 ネストされた要素(内部クラス、またはクラス内の関数または変数)にpublic修飾子を適用すると、コンテナーにアクセスできるすべてのコードがこの要素にもアクセスできます。

例えば:

class Public {
    val i = 1

    fun doSomething() {
    }
}

クラスPublicは、コードベース全体のどこからでもアクセスできます。“val i」および「fundoSomething()”は、Public.にアクセスできるすべてのものからアクセスできます。

2.2. プライベートビジビリティ

ほとんどの場合に使用される他の修飾子はprivateです。 これは、publicとほぼ正反対の意味を持ちます。つまり、誰もアクセスできないということです。

実際には、in Kotlin it means that only code declared inside the same scope can access itです。 これは、Kotlinが同じファイル内で複数のトップレベル宣言を許可しているという理由だけでJavaとは微妙に異なります。privateトップレベル要素は同じファイル内の他のすべてからアクセスできます。 それ以外は、ルールは同じです。 例えば:

例えば:

private class Private {
    private val i = 1

    private val doSomething() {
    }
}

クラスPrivateは、同じソースファイル内からのみアクセスできます。“vali」および「fundoSomething()”は、クラスPrivate内からのみアクセスできます。

2.3. 保護された可視性

The protected modifier in Kotlin means that it is strictly accessible only by the declaring class and subclasses。 これは、ほとんどの人がJavaの動作を期待しているのと同じですが、Javaの動作とは微妙に異なります。

Javaでは、protected修飾子を使用して、同じパッケージ内の他の要素から要素にアクセスすることもできます。 たとえば、次のクラスファイルがあるとします。

class A {
    protected val i = 1
}

次のファイルはKotlinで正常に機能します。

class B : A() {
    fun getValue() : Int {
        return i
    }
}

次のファイルはJavaでは機能しますが、Kotlinでは機能しません。

class C {
    fun getValue() : Int {
        val a = A()
        return a.i
    }
}

そして、以下はJavaでもKotlinでも動作しません:

class D {
    fun getValue() : Int {
        val a = A()
        return a.i
    }
}

さらに、in Kotlin protected becomes the default visibility when we are overriding a protected element from a superclass。 これは、必要に応じて明示的にpublicに変更できます。これは、何かをpublicとして明示的に宣言する必要がある主な場合です____。

2.4. パッケージ - プライベート/デフォルトの可視性

Javaには、「package-private」(「default」とも呼ばれる)と呼ばれるアクセス修飾子があります。 これは、要素に修飾子が配置されていない場合に使用されます。 これは、同じパッケージ内のすべてのコードがアクセスできるが、サブクラスを含む別のパッケージ内のコードはアクセスできないことを意味します。

Kotlin does not currently have any support for this modifier at all。ただし、これは将来変更される可能性があります。 この理由は、保護が提供されないためです。誰でも同じパッケージでコードを定義し、別のjarファイルからでも要素にアクセスできます。

2.5. 内部の可視性

Kotlinは、Javaが現在サポートしていないオプション(internal)に新しい修飾子を追加します。 This modifier means that any code declared in the same module that is not otherwise restricted can access this element。 (モジュールは基本的にJarファイルです。)

これは、OSGiなどを使用してJavaで可能ですが、現時点ではその言語にネイティブではありません。 Java 9は、公開識別子を選択的にエクスポートできるようにすることで、より達成しやすい概念をもたらします。

これは、APIと実装を作成するための大きな利点を追加します。 APIインターフェイスをpublicとして記述し、メインの実装をpublicクラスとして記述し、依存するすべてのサポートコードをinternalとして記述できます。 これを行うと、外部コードがAPIを強制的に通過し、内部コードにアクセスできなくなります。 例えば:

package com.example.modifiers

internal class Internal {
}

class Public {
    internal val i = 1

    internal fun doSomething() {
    }
}

クラスInternalは、同じモジュール内からのみアクセスできます。 “val i”“fun doSomething()”も、それらが含まれるクラスはどこからでもアクセスできますが、同じモジュール内からのみアクセスできます。

3. 概要

この記事では、Kotlinの可視性修飾子について説明しました。

ほとんどの場合、Kotlinの可視性修飾子ルールはJavaに期待するものと同じように機能します。 ただし、大きな違いがあります。これは、internalスコープの導入です。これは、大規模なプロジェクトに非常に役立ちます。