目次 | 前項目 | 次項目 内部クラス仕様


Java コードにおいて内部クラスが this という考え方にどのように影響するか?

トップレベルクラス T のコードは、キーワード this によって直接、または T のインスタンスメンバの 1 つを命名することによって間接的に、カレントインスタンスを利用できることを思い出してください。カレントインスタンスの考え方は拡張され、内部クラスは 1 つ以上のカレントインスタンスを持ちます。これによって、内部クラス C のコードは C のカレントインスタンスと同様に、その外部クラスの親インスタンスと関連して実行できるようになります。

アダプタクラスの最初の例で、Enumerator コードは 2 つのカレントインスタンス、親 FixedStack および Enumerator オブジェクト自身を持ちます。もっと一般的には、内部クラス C の本体全体の内部に、 C のカレントインスタンス、さらに、C を囲むすべての内部クラスのカレントインスタンス、最後に最奥の囲むトップレベルクラスのカレントインスタンスがあります。(static クラスはトップレベルであり、内部クラスではありません。そのため、カレントインスタンスの列挙は最初の static キーワードで終りです。)

トップレベルクラスは複数のカレントインスタンスを持ちません。トップレベルクラス T の非 static コード内では、型 T の 1 つのカレントインスタンスがあります。トップレベルクラス Tstatic コード内では、カレントインスタンスはありません。これはパッケージメンバであるトップレベルクラスについては常に true であり、他のトップレベルクラスの static メンバであるトップレベルクラスについても true です。これはすべてのパッケージメンバが暗示的にずっと static であったかのようです。

すべてのクラスにおいて、各カレントインスタンスを明示的に命名するか、またはそのメンバが使用されるとき暗示的な役割を演じさせることができます。すべてのカレントインスタンスは、あたかもそれが名前であるかのように、明示的にキーワード this を修飾して参照することができます: FixedStack.thisEnumerator.thisなどのように。(この言語によって、内部クラスが親クラスのどれとも同じ名前を持つことを禁じられるため、この表記法は常に有効です。) いつものように、最奥のカレントインスタンスは修飾されていないキーワード this で命名できます。

インスタンス変数参照 m はフィールド参照式 this.m と同じ意味を持ち、そのためカレントインスタンスが暗示的に使用されることを覚えておいてください。所定のコード内では、全カレントクラスのメンバすべてがスコープ内にあり、使用可能です(干渉スコープが覆い隠す名前を除いて)。メンバの簡単な名前は、そのクラスで名前が発見されたカレントインスタンスによって暗示的に修飾されます。(親クラスのすべての static メンバは常に使用可能です。)

とりわけ、Java コードは、すべてのカレントインスタンスのすべてのメソッドを直接使用することができます。クラスのスコープは過負荷には影響しません: 内部クラスが 1 つの print メソッドを持っている場合、修飾名のないメソッド名 print はそのメソッドを参照しますが、親クラスの 10 個の print メソッドのどれも参照できません。

親クラスおよびインスタンス生成

内部クラス C親インスタンスについて述べることは時に有用です。これは C 自身のインスタンスでなく、 C 内部のどれかのカレントインスタンスとして定義されます。C のすべてのインスタンスは、親インスタンスと永久的に関連します。

構築子が起動されるとき、新しいオブジェクトが親インスタンスと共に供給される必要があります。この親インスタンスは、新しいオブジェクトが実行するすべてのコードのカレントインスタンスになります。(親インスタンスのレイヤがある場合、最奥のものが要求され、これは代わりに他のすべてを決定します。) 親インスタンスは、キーワード new を修飾することによって、明示的に指定が可能です:

    class Automobile {
        class Wheel {
            String hubcapType;
            float radius;
        }
    
        Wheel leftWheel = this. new Wheel();
        Wheel rightWheel = this. new Wheel();
        Wheel extra;
    
        static void thirdWheel(Automobile car) {
            if (car.extra == null) {
                car.extra = car. new Wheel();
            }
            return car.extra;
        }
    }
    
    class WireRimWheel extends Automobile.Wheel {
        WireRimWheel(Automobile car, float wireGauge) {
            car. super();
        }
    }

内部クラス C のサブクラスは親インスタンスを C の構築子に渡す必要があります。これは今示したように、キーワード super を明示的に修飾することによって行われます。デフォルトでは、呼び出し側のカレントインスタンスが、新しい内部オブジェクトの親インスタンスになります。以前の例では、式 new Enumerator() は明示的に修飾された this.new Enumerator() と同等です。このデフォルトはほとんど常に正しいですが、あるアプリケーション(ソースコードジェネレータなど)では、それを時にオーバーライドする必要があるかもしれません。


目次 | 前項目 | 次項目

内部クラス仕様 (HTML generated by dkramer on March 15, 1997)
Copyright (c) 1996, 1997 Sun Microsystems, Inc. All rights reserved
コメントや訂正は john.rose@eng.sun.com 宛てに送ってください。