English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
1.何が内部クラスか63;
クラス内に定義されたクラスは内部クラスと呼ばれます。
public class Out{ class In{ //この場合、Inは内部クラスです。 } }
2.なぜ内部クラスを使用するのか63;
1)封装を強化し、内部クラスを外部クラス内に隠して、他のクラスからのアクセスを許可しません。
2)内部クラスはコードの可読性や可維持性を向上させます。
3.内部クラスの分類
内部クラスの分類については、メンバー変数の分類と比較できます。
異なる修飾子や定義位置に基づいて、メンバー変数を以下のように詳細に分類できます:クラスメンバー変数、インスタンスメンバー変数、ローカル変数。
内部クラスが外部クラスのメンバーとして見なされる場合、内部クラスはpublicを使用できます。/デフォルト/protected/private修飾子。また、static修飾子も可能です。
同様に、内部クラスも異なる修飾子を使用したり、異なる位置で定義されたりするため、以下のように分類されます。4クラス:
1)インスタンス内部クラス:static修飾子を使用していない内部クラスです。
2)静的内部クラス:static修飾子を使用する内部クラスです。
3)ローカル内部クラス:メソッド内で定義される内部クラスです。
4)匿名内部クラス:一度のみ使用可能で、内部クラスの特殊な場合です。
3.1インスタンス内部クラス:
1)定義:インスタンス内部クラスは、static修飾子を使用していない内部クラスです。これは、インスタンス内部クラスが外部クラスのオブジェクトに属しており、外部クラス自体に属していないことを示しています(フィールドに似た比喩)。
2)インスタンス内部クラスを作成します
//外部クラス class Outter { // インスタンス内部クラス: static修飾子を使用していません class Inner { } } public class InnerDemo1 { public static void main(String[] args) { // インスタンス内部クラスを作成する場合、static修飾子を使用していないため、外部クラスのオブジェクトに属しており、したがって、インスタンス内部クラスを作成する前に外部クラスのオブジェクトが存在する必要があります。 Outter out = new Outter(); // 外部クラスオブジェクトを通じて内部クラスオブジェクトを作成します。 Outter.Inner in = out.new Inner(); } }
3)特点:
a.インスタンス内部クラスの作成プロセスからわかるように、内部クラスオブジェクトがある場合、必ず外部クラスオブジェクトがあります。
b.インスタンス内部クラスのインスタンスは自動的に外部クラスのインスタンスのリファレンスを保持し、インスタンス内部クラスは無条件に外部クラスのすべてのフィールドやメソッドにアクセスできます。
注意:メンバー内部クラスが外部クラスと同名のメンバー変数やメソッドを持っている場合、隠し現象が発生します。
外部クラスでは内部クラスのメンバーに直接アクセスすることはできず、まずメンバー内部クラスのオブジェクトを作成し、そのオブジェクトを指すリファレンスを通じてアクセスする必要があります。
//外部クラス class Outter { private String name = "out"; private Integer age = 17; // インスタンス内部クラス: static修飾子を使用していません class Inner { private Integer age = 18; // 隠し現象、外部クラスのageを隠します。 Inner() { // 特徴:1.インスタンス内部クラスは外部クラスのメンバーに直接アクセスできます。 // 2.インスタンス内部クラスと外部クラスが同じ名前のフィールドやメソッドを持つと、隠し現象が発生します。 System.out.println(name + this.age);// 出力out18 // 外部クラスのageを使用する場合、文法:外部クラス.this.age System.out.println(Outter.this.age);// 输出17 } } }
まとめ:簡単に言えば、変数の範囲を見てください。外部クラスのメンバー変数の範囲は外部クラス全体に広がります。内部クラスは外部クラス内にあります(外部クラスのフィールドとして見ることができます)。したがって、内部クラスは外部クラスにアクセスできます。外部クラスが内部クラスのメンバーにアクセスするには、このように理解できます:内部クラスのメンバーは内部クラスに属し、内部クラス内で有効です。内部クラスが存在しない場合、そのメンバー変数も存在しません。したがって、外部クラスは直接内部クラスのメンバーにアクセスできず、まずメンバー内部クラスのオブジェクトを作成して、そのオブジェクトを指すリファレンスを通じてアクセスする必要があります。
3.2静的内部クラス
1)定義: static修飾子を使用する内部クラス。したがって、この内部クラスは外部クラス自体に属しており、外部クラスのオブジェクトに属しません。
2)静的内部クラスの作成
//外部クラス class Outter { // 静的内部クラス: static修飾子を使用 static class Inner { } } public class InnerDemo2 { public static void main(String[] args) { // 静的内部クラスは外部クラス自体に属しており、外部クラスのクラス名を通じて直接アクセスできます(フィールドに似たものです)。 Outter.Inner in = new Outter.Inner(); } }
3)特点:
a.内部クラスのインスタンスを作成する際には、外部クラスのインスタンスを作成する必要はありません。
b.静的内部クラスは外部クラスの静的メンバーに直接アクセスできます。外部クラスのインスタンスメンバーにアクセスするには、外部クラスのインスタンスを通じてアクセスする必要があります。
簡単に言えば、静的メンバーはクラスに属し、非静的メンバーはオブジェクトに属します。外部クラスのインスタンスメンバー(非静的メンバー)にアクセスするには、もちろん外部クラスのオブジェクトを保持する必要があります。そのため、静的内部クラスの作成は外部クラスのオブジェクトが必要ないため、外部クラスのインスタンスメンバーにアクセスするには、外部クラスのインスタンスを通じてアクセスする必要があります。
c.静的内部クラスでは静的メンバーとインスタンスメンバーを定義できます。
d.テストクラスは完全なクラス名を使用して静的内部クラスの静的メンバーに直接アクセスできます。
//外部クラス class Outter { static String name = "outter"; public Integer age = 17; // 静的内部クラス: static修飾子を使用 static class Inner { Inner() { // 静的内部クラスは外部クラスの静的メンバーに直接アクセスできます System.out.println(name);// 输出 outter // 访问外部类的实例成员,必须通过外部类的实例去访问。 System.out.println(new Outter().age);// 输出 17 } } }
3.3局部内部类(几乎用不到)
1)定义:在方法中定义的内部类,其可见范围是当前方法,和局部变量是同一个级别,所以局部内部类只能在方法中使用。
注意,局部内部类和方法里面的局部变量一样,是不能有public、protected、private以及static修饰符的。
public class InnerDemo3 { public static void main(String[] args) { // 局部内部类 class Inner { } } }
2)特点:
a.局部内部类和实例内部类一样,不能包含静态成员。(局部内部类属于方法,而静态成员属于类)
b.局部内部类和实例内部类,可以访问外部类的所有成员。
c.局部内部类访问的局部变量必须使用final修饰,在Java8中是自动隐式加上final(语法糖).
原因:当方法被调用运行完毕之后,当前方法的栈帧被销毁,方法内部的局部变量的空间全部销毁。但内部类对象可能还在堆内存中,要直到没有被引用时才会消亡。此时就会出现一种情况:内部类要访问一个不存在的局部变量。为了避免该问题,我们使用final修饰局部变量,从而变成常量,永驻内存空间,即使方法销毁之后,该局部变量也在内存中,对象可以继续持有。
public class InnerDemo3 { public static void main(String[] args) { int age = 17; final int num = 15; // 局部内部类 class Inner { public void test() { // 报错:Cannot refer to a non-final variable age inside an inner class defined in a different method System.out.println(age); System.out.println(num);// 正确 } } } }
3.4匿名内部类(使用最频繁)
1:定义:匿名内部类是一个没有名称的局部内部类,适合于只使用一次的类。
2创建匿名内部类:
匿名内部类本身没有构造器,但是会调用父类构造器。一般来说,匿名内部类用于继承其他类或是实现接口,并不需要增加额外的方法,只是对继承方法的实现或是重写。
注意:匿名内部类必须继承一个父类或者实现一个接口,但最多只能一个父类或实现一个接口。
//インターフェースを定義 interface Person { public void eat(); } public class AnonymousDemo { public static void main(String[] args) { // 匿名内部クラスの使用 Person p = new Person() { public void eat() { System.out.println("eat something"); } }; p.eat(); } }
4.まとめ
5.インタビューキャスト
public class Outer { public void someOuterMethod() { // Line 3 } public class Inner { } public static void main(String[] argv) { Outer o = new Outer(); // Line 8 } } /* * Which instantiates an instance of Inner&63; A. new Inner(); // At line 3 B. new Inner(); // At line 8 C. new o.Inner(); // At line 8 D. new Outer.Inner(); // At line 8 */
答えA.new Inner();は、既にOuterクラスのオブジェクトが存在することを意味します。
line 8 正しい書き方は:o.new Inner();
これで本文のすべての内容が終わります。本文の内容が皆様の学習や仕事に少しでも役立つことを願っています。また、ナイアラガイドのサポートを多くいただければ幸いです。
声明:本文の内容はインターネットから取得しており、著作権者はすべての権利を保有しています。インターネットユーザーが自発的に貢献し、自己でアップロードしたものであり、本サイトは所有権を持ちません。また、人工的な編集は行われていません。著作権侵害を疑う内容があれば、メールを送信してください:notice#oldtoolbag.com(メールを送信する際、#を@に置き換えてください。報告を行い、関連する証拠を提供してください。一旦確認が取れましたら、本サイトは即座に侵害を疑われるコンテンツを削除します。)