Javaにおける変数とメソッドの隠蔽

Javaでの変数とメソッドの非表示

1. 前書き

このチュートリアルでは、we’re going to learn about variable and method hiding in the Java language

まず、これらの各シナリオの概念と目的を理解します。 その後、ユースケースに飛び込み、さまざまな例を検討します。

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つの異なる場所でmessage variableが宣言されています。 コンストラクター内で宣言されたローカル変数と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

In most cases, we should avoid creating variables with the same name both in parent and child classes。 代わりに、private のような適切なアクセス修飾子を使用し、その目的のためにgetter / setterメソッドを提供する必要があります。

3. メソッドの非表示

メソッドの非表示は、Javaの階層構造で発生する場合があります。 子クラスが親クラスの静的メソッドと同じ署名を持つ静的メソッドを定義する場合、子のメソッドは親クラスのメソッドhidesになります。 staticキーワードの詳細については、this write-up is a good place to start.

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

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

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. メソッドの非表示とオーバーライド

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

On the other hand, method hiding works with static ones. Therefore it’s determined at compile time

4. 結論

In this article, we went over the concept of method and variable hiding in Java。 変数の非表示とシャドウイングのさまざまなシナリオを示しました。 この記事の重要なハイライトは、メソッドのオーバーライドと非表示の比較です。

いつものように、完全なコードはover on GitHubで利用できます。