1. 序章

このチュートリアルでは、Java言語での変数とメソッドの非表示について学習します。

まず、これらの各シナリオの概念と目的を理解します。 その後、ユースケースを詳しく調べ、さまざまな例を検討します。

2. 可変隠蔽

変数の非表示は、外部スコープに既にあるものと同じ名前のローカルスコープでプロパティを宣言するときに発生します。

例にジャンプする前に、Javaで可能な変数スコープを簡単に要約してみましょう。 次のカテゴリでそれらを定義できます。

  • ローカル変数–中括弧を使用したコードの任意のブロックで、メソッド、コンストラクターなどのコードで宣言されます
  • インスタンス変数–クラス内で定義され、オブジェクトのインスタンスに属します
  • クラスまたはstatic変数– staticキーワードを使用してクラスで宣言されます。 それらはクラスレベルのスコープを持っています。

次に、変数の個々のカテゴリごとに、例を使用して非表示について説明します。

2.1. ローカルの力

HideVariableクラスを見てみましょう。

public class HideVariable {

    private String message = "this is instance variable";

    HideVariable() {
        String message = "constructor local variable";
        System.out.println(message);
    }

    public void printLocalVariable() {
        String message = "method local variable";
        System.out.println(message);
    }

    public void printInstanceVariable() {
        String message = "method local variable";
        System.out.println(this.message);
    }
}

ここでは、メッセージ変数が4つの異なる場所で宣言されています。 コンストラクターと2つのメソッドの内部で宣言されたローカル変数は、インスタンス変数をシャドウイングしています。

オブジェクトの初期化とメソッドの呼び出しをテストしてみましょう。

HideVariable variable = new HideVariable();
variable.printLocalVariable();

variable.printInstanceVariable();

上記のコードの出力は次のとおりです。

constructor local variable
method local variable
this is instance variable

ここで、最初の2つの呼び出しはローカル変数を取得しています。

ローカルスコープからインスタンス変数にアクセスするには、 printInstanceVariable()メソッドに示されているようにthisキーワードを使用できます。

2.2. 隠蔽と階層

同様に、子クラスと親クラスの両方に同じ名前の変数がある場合、子の変数はその変数を親から隠します。

親クラスがあるとしましょう:

public class ParentVariable {

    String instanceVariable = "parent variable";

    public void printInstanceVariable() {
        System.out.println(instanceVariable);
    }
}

その後、子クラスを定義します。

public class ChildVariable extends ParentVariable {

    String instanceVariable = "child variable";

    public void printInstanceVariable() {
        System.out.println(instanceVariable);
    }
}

それをテストするために、2つのインスタンスを初期化しましょう。 1つは親クラスを持ち、もう1つは子クラスを持ち、それぞれで printInstanceVariable()メソッドを呼び出します。

ParentVariable parentVariable = new ParentVariable();
ParentVariable childVariable = new ChildVariable();

parentVariable.printInstanceVariable();
childVariable.printInstanceVariable();

出力には、プロパティが非表示になっていることが示されています。

parent variable
child variable

ほとんどの場合、親クラスと子クラスの両方で同じ名前の変数を作成することは避けてください。 代わりに、 private のような適切なアクセス修飾子を使用し、その目的のためにゲッター/セッターメソッドを提供する必要があります。

3. メソッドの非表示

メソッドの非表示は、Javaの任意の階層構造で発生する可能性があります。 子クラスが親クラスの静的メソッドと同じシグネチャを持つ静的メソッドを定義する場合、子のメソッドは親クラスのメソッドを非表示にします。  static キーワードの詳細については、この記事から始めるとよいでしょう。

インスタンスメソッドに関連する同じ動作は、メソッドオーバーライドと呼ばれます。 チェックアウトをオーバーライドするメソッドの詳細については、ガイドをご覧ください。

それでは、この実用的な例を見てみましょう。

public class BaseMethodClass {

    public static void printMessage() {
        System.out.println("base static method");
    }
}

BaseMethodClass には、単一の printMessage()staticメソッドがあります。

次に、基本クラスと同じシグニチャを持つ子クラスを作成しましょう。

public class ChildMethodClass extends BaseMethodClass {

    public static void printMessage() {
        System.out.println("child static method");
    }
}

仕組みは次のとおりです。

ChildMethodClass.printMessage();

printMessage()メソッドを呼び出した後の出力:

child static method

ChildMethodClass.printMessage()は、BaseMethodClassのメソッドを非表示にします。

3.1. メソッドの非表示とオーバーライド

静的メソッドはポリモーフィックではないため、非表示はオーバーライドのようには機能しません。 オーバーライドは、インスタンスメソッドでのみ発生します。 遅延バインディングをサポートしているため、どのメソッドが呼び出されるかは実行時に決定されます。

一方、メソッドの非表示は静的なメソッドで機能します。 したがって、コンパイル時に決定されます

4. 結論

この記事では、Javaでのメソッドと変数の非表示の概念について説明しました。 変数の非表示とシャドウイングのさまざまなシナリオを示しました。 この記事の重要なハイライトは、メソッドのオーバーライドと非表示の比較でもあります。

いつものように、完全なコードはGitHubから入手できます。