この記事では、主に Java 内部クラスの詳細な例に関する関連情報を紹介します。この記事を通じて、皆さんが Java 内部クラスの使い方を理解し、使いこなすことができるように願っています。必要な方は、
Java 内部クラスの詳細な例を参照してください。
あるクラスの定義を別のクラスの定義の中に置くことができます。これは内部クラスです。
内部クラスは非常に便利な機能ですが、理解して使用するのが難しいです (私は内部クラスを使用したことがなく、内部クラスについて少ししか知りません)。
初対面
内部クラスは、外部からは非常に理解しやすいですが、クラスの中にクラスを定義しているだけです。
public class OuterClass { private String name ; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } class InnerClass{ public InnerClass(){ name = "chenssy"; age = 23; } } }
ここでの InnerClass は内部クラスです。初心者にとって、内部クラスはあまり使用されません (スイング登録イベントでのみ使用されるようです)。改善すれば、その魅力に気づき、それを使用してプログラム構造をよりエレガントに設計できるようになります。内部クラスを使用する前に、なぜ内部クラスを使用する必要があるのか、また内部クラスによってどのようなメリットがもたらされるのかを理解する必要があります。
1. 内部クラスを使用する理由
なぜ内部クラスを使用するのでしょうか? 「Think in Java」には次の文があります。 内部クラスを使用する最も魅力的な理由は、各内部クラスが独立して (インターフェース) 実装を継承できるため、外部クラスが (インターフェース) 実装を継承しているかどうかに関係なく、実装が存在しないことです。内部クラスへの影響。
私たちのプログラミングでは、インターフェースを使用して解決するのが難しい問題が時々発生します。このとき、内部クラスによって提供される機能を使用して、複数の具体クラスまたは抽象クラスを継承することで、これらのプログラミング問題を解決できます。インターフェイスは問題の一部を解決するだけであり、内部クラスは多重継承の解決策をより完全にするものであると言えます。
public interface Father { } public interface Mother { } public class Son implements Father, Mother { } public class Daughter implements Father{ class Mother_ implements Mother{ } }
実際、この例では内部クラスを使用する利点がわかりませんが、Father と Mother がインターフェイスではなく、抽象クラスまたは具象クラスだったらどうでしょうか?現時点では、多重継承を実現するには内部クラスのみを使用できます。
実際、内部クラスを使用する最大の利点は、多重継承の問題をうまく解決できることです。しかし、多重継承の問題を解決する必要がない場合は、当然他のコーディング方法を使用できます。内部クラスを使用すると、次のような機能が得られます (「Think in Java」から抜粋):
1. 内部クラスは複数のインスタンスを使用でき、各インスタンスは独自のステータス情報を持ち、他の周辺オブジェクトの情報から独立しています。 。
2. 単一の周辺クラスでは、複数の内部クラスが同じインターフェイスを異なる方法で実装したり、同じクラスを継承したりできます。
3. 内部クラスのオブジェクトが作成される時間は、外部クラスのオブジェクトの作成に依存しません。
4. 内部クラスには紛らわしい「is-a」関係はなく、独立したエンティティです。
5. 内部クラスはより適切なカプセル化を提供します。周辺クラスを除き、他のクラスはそれにアクセスできません。
2. 内部クラスの基本
このパートでは、主に内部クラスが外部クラスのプロパティとメソッドを使用する方法、および .this と .new の使用方法を紹介します。
内部クラスを作成すると、外部クラスとの目に見えない接続が確立され、この接続に基づいて外部クラスの要素に無制限にアクセスできます。
public class OuterClass { private String name ; private int age; /**省略getter和setter方法**/ public class InnerClass{ public InnerClass(){ name = "chenssy"; age = 23; } public void display(){ System.out.println("name:" + getName() +" ;age:" + getAge()); } } public static void main(String[] args) { OuterClass outerClass = new OuterClass(); OuterClass.InnerClass innerClass = outerClass.new InnerClass(); innerClass.display(); } } -------------- Output: name:chenssy ;age:23
このアプリケーションでは、内部の InnerClass は、プライベートに変更されているにもかかわらず、外部クラスの InnerClass のプロパティにシームレスにアクセスできることがわかります。これは、外部クラスの内部クラス オブジェクトを作成するとき、外部クラスのメンバーにアクセスする限り、内部クラス オブジェクトはその外部クラス オブジェクトへの参照を確実に取得するため、この参照を使用します。囲んでいるクラス。
実際、このアプリケーションでは、内部クラスを参照する方法も確認しました。内部クラスを参照するには、このオブジェクトのタイプ、OuterClasName.InnerClassName を指定する必要があります。同時に、内部クラス オブジェクトを作成する必要がある場合は、外部クラス オブジェクトを使用して、.new を通じて内部クラスを作成する必要があります:OuterClass.InnerClass innerClass = innerClass.new InnerClass();。
同時に、外部クラス オブジェクトへの参照を生成する必要がある場合は、OuterClassName.this を使用して、外部クラスへの参照を正しく生成できます。もちろん、これはコンパイル時に認識されるため、実行時のコストはかかりません。
/** * Java学习交流QQ群:589809992 我们一起学Java! */ public class OuterClass { public void display(){ System.out.println("OuterClass..."); } public class InnerClass{ public OuterClass getOuterClass(){ return OuterClass.this; } } public static void main(String[] args) { OuterClass outerClass = new OuterClass(); OuterClass.InnerClass innerClass = outerClass.new InnerClass(); innerClass.getOuterClass().display(); } } ------------- Output: OuterClass...
この時点で、内部クラスはコンパイル時の概念であり、コンパイルが成功すると、それと外部クラスは 2 つの完全に異なるクラスに属することを明確にする必要があります (もちろん、間にはまだ接続があります)。彼ら)。 OuterClass という名前の周辺クラスと InnerClass という名前の内部クラスの場合、コンパイルが成功すると、OuterClass.class とOuterClass$InnerClass.class という 2 つのクラス ファイルが表示されます。
Java では、内部クラスは主にメンバー内部クラス、ローカル内部クラス、匿名内部クラス、静的内部クラスに分類されます。
3. メンバー内部クラス
成员内部类也是最普通的内部类,它是外围类的一个成员,所以他是可以无限制的访问外围类的所有 成员属性和方法,尽管是private的,但是外围类要访问内部类的成员属性和方法则需要通过内部类实例来访问。
在成员内部类中要注意两点,第一:成员内部类中不能存在任何static的变量和方法;第二:成员内部类是依附于外围类的,所以只有先创建了外围类才能够创建内部类。
public class OuterClass { private String str; public void outerDisplay(){ System.out.println("outerClass..."); } public class InnerClass{ public void innerDisplay(){ //使用外围内的属性 str = "chenssy..."; System.out.println(str); //使用外围内的方法 outerDisplay(); } } /*推荐使用getxxx()来获取成员内部类,尤其是该内部类的构造函数无参数时 */ public InnerClass getInnerClass(){ return new InnerClass(); } public static void main(String[] args) { OuterClass outer = new OuterClass(); OuterClass.InnerClass inner = outer.getInnerClass(); inner.innerDisplay(); } } -------------------- chenssy... outerClass...
推荐使用getxxx()来获取成员内部类,尤其是该内部类的构造函数无参数时 。
四、局部内部类
有这样一种内部类,它是嵌套在方法和作用于内的,对于这个类的使用主要是应用与解决比较复杂的问题,想创建一个类来辅助我们的解决方案,到那时又不希望这个类是公共可用的,所以就产生了局部内部类,局部内部类和成员内部类一样被编译,只是它的作用域发生了改变,它只能在该方法和属性中被使用,出了该方法和属性就会失效。
对于局部内部类实在是想不出什么好例子,所以就引用《Think in java》中的经典例子了。
定义在方法里:
/** * Java学习交流QQ群:589809992 我们一起学Java! */ public class Parcel5 { public Destionation destionation(String str){ class PDestionation implements Destionation{ private String label; private PDestionation(String whereTo){ label = whereTo; } public String readLabel(){ return label; } } return new PDestionation(str); } public static void main(String[] args) { Parcel5 parcel5 = new Parcel5(); Destionation d = parcel5.destionation("chenssy"); } }
定义在作用域内:
public class Parcel6 { private void internalTracking(boolean b){ if(b){ class TrackingSlip{ private String id; TrackingSlip(String s) { id = s; } String getSlip(){ return id; } } TrackingSlip ts = new TrackingSlip("chenssy"); String string = ts.getSlip(); } } public void track(){ internalTracking(true); } public static void main(String[] args) { Parcel6 parcel6 = new Parcel6(); parcel6.track(); } }
五、匿名内部类
在做Swing编程中,我们经常使用这种方式来绑定事件
button2.addActionListener( new ActionListener(){ public void actionPerformed(ActionEvent e) { System.out.println("你按了按钮二"); } });
我们咋一看可能觉得非常奇怪,因为这个内部类是没有名字的,在看如下这个例子:
/** * Java学习交流QQ群:589809992 我们一起学Java! */ public class OuterClass { public InnerClass getInnerClass(final int num,String str2){ return new InnerClass(){ int number = num + 3; public int getNumber(){ return number; } }; /* 注意:分号不能省 */ } public static void main(String[] args) { OuterClass out = new OuterClass(); InnerClass inner = out.getInnerClass(2, "chenssy"); System.out.println(inner.getNumber()); } } interface InnerClass { int getNumber(); } ---------------- Output:
这里我们就需要看清几个地方
1、 匿名内部类是没有访问修饰符的。
2、 new 匿名内部类,这个类首先是要存在的。如果我们将那个InnerClass接口注释掉,就会出现编译出错。
3、 注意getInnerClass()方法的形参,第一个形参是用final修饰的,而第二个却没有。同时我们也发现第二个形参在匿名内部类中没有使用过,所以当所在方法的形参需要被匿名内部类使用,那么这个形参就必须为final。
4、 匿名内部类是没有构造方法的。因为它连名字都没有何来构造方法。
六、静态内部类
在java提高篇——关键字static中提到Static可以修饰成员变量、方法、代码块,其他它还可以修饰内部类,使用static修饰的内部类我们称之为静态内部类,不过我们更喜欢称之为嵌套内部类。静态内部类与非静态内部类之间存在一个最大的区别,我们知道非静态内部类在编译完成之后会隐含地保存着一个引用,该引用是指向创建它的外围内,但是静态内部类却没有。没有这个引用就意味着:
1、 它的创建是不需要依赖于外围类的。
2、 它不能使用任何外围类的非static成员变量和方法。
/** * Java学习交流QQ群:589809992 我们一起学Java! */ public class OuterClass { private String sex; public static String name = "chenssy"; /** *静态内部类 */ static class InnerClass1{ /* 在静态内部类中可以存在静态成员 */ public static String _name1 = "chenssy_static"; public void display(){ /* * 静态内部类只能访问外围类的静态成员变量和方法 * 不能访问外围类的非静态成员变量和方法 */ System.out.println("OutClass name :" + name); } } /** * 非静态内部类 */ class InnerClass2{ /* 非静态内部类中不能存在静态成员 */ public String _name2 = "chenssy_inner"; /* 非静态内部类中可以调用外围类的任何成员,不管是静态的还是非静态的 */ public void display(){ System.out.println("OuterClass name:" + name); } } /** * @desc 外围类方法 * @author chenssy * @data 2013-10-25 * @return void */ public void display(){ /* 外围类访问静态内部类:内部类. */ System.out.println(InnerClass1._name1); /* 静态内部类 可以直接创建实例不需要依赖于外围类 */ new InnerClass1().display(); /* 非静态内部的创建需要依赖于外围类 */ OuterClass.InnerClass2 inner2 = new OuterClass().new InnerClass2(); /* 方位非静态内部类的成员需要使用非静态内部类的实例 */ System.out.println(inner2._name2); inner2.display(); } public static void main(String[] args) { OuterClass outer = new OuterClass(); outer.display(); } } ---------------- Output: chenssy_static OutClass name :chenssy chenssy_inner OuterClass name:chenssy
上面这个例子充分展现了静态内部类和非静态内部类的区别。
到这里内部类的介绍就基本结束了!对于内部类其实本人认识也只是皮毛,逼近菜鸟一枚,认知有限!我会利用这几天时间好好研究内部类!
以上がJava 内部クラスのコード例の共有の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。