Java内部クラス、匿名内部クラスの使用方法と注意事項


Java開発における「内部クラス」の応用シーンはそれほど多くありませんが、面接では多かれ少なかれ取り上げられるので、今日は皆さんを復習してみましょう.
本文:
「内部クラス」は、単純に、既知のクラスの内部に定義されたクラスを「内部クラス」と呼びます.既知のクラスの内部に定義されているため、疲れた特徴を備えているだけでなく、多くの面で普通のクラスとは異なる表現があります.
次に、3つの側面から内部クラスの使用を説明し、内部クラスの概念を検証するつもりです.
一、一般クラスで内部クラスを定義する(一般的ではない)
内部クラスには通常のクラスとは異なる特性がありますが、クラスは結局クラスであり、クラスがオブジェクトを作成し、そのメソッドを呼び出して機能を実行する必要があります.これはクラスを定義する意味です.
内部クラスのプロパティがどのように呼び出されているかを例に挙げます.
public class innerTest {
	int num = 100;
	private class inner{
		int num = 200;
		public void print(){
			int num = 500;
			System.out.println(num);				//     
			System.out.println(this.num);			//     
			System.out.println(innerTest.this.num);	//     
		}
	}
	public static void main(String[] args) {
		innerTest innerT = new innerTest();
		innerTest.inner inner = inner.new inner();
		inner .print();
		System.out.println(innerT.num + inner .num);	//      num  
	}
}
//        :500,200,100,300

内部クラスの特性:
  • 「内部クラス」では、属性を定義できます.これらの属性は、その存在する通常のクラスによってアクセスされ、さらには「内部クラス」のプライベート属性(private)にアクセスできます.これらの属性が重複する場合、アクセス限定修飾が必要です.
  • 普通クラスの内部は複数の内部クラスとインタフェースを定義することができ、継承、実現の関係を備えている.
  • はstaticキーワードで、トップクラスの内部クラスにアップグレードされ、普通のクラスと同じ特徴を備え、そっくりである.
  • 「内部クラス」はさらにネストでき、オブジェクトを構築する際にはレイヤ別に構築する必要があります.

  • 二、方法で内部クラスを定義する(了解)
    メソッドでは「内部クラス」を定義することもでき、メソッドの「内部クラス」はjdk 1でイベント処理で一般的である.8バージョン以前に「内部クラス」がメソッド内のローカル属性にアクセスする必要がある場合、このローカル属性はfinalで修飾する必要があります.jdk1.8バージョンではこの操作は必要ありませんが、その本質はfinalであり、修正することはできません.例を見てください.
    public class innerTest {
    	public void innerMethod(){
    		int num = 100;
    		class innerClass{
    			public void print(){
    				System.out.println("         ,      :"+num);
    			}
    		}
    		innerClass inner = new innerClass();
    		inner.print();
    	}
    	public static void main(String[] args) {
    		innerTest inner = new innerTest();
    		inner.innerMethod();
    	}	
    }
    //     :         ,      :100
    

    三、匿名内部クラス(常用)
    実際の開発では、上記の方法で内部クラスを定義した場合の代わりに、匿名の内部クラスを使用することが多いが、その書き方は簡略化されているが、意味は同じである.以下に紹介する.
    名前の通り、匿名の内部クラス、つまり名前のない内部クラスです.名前がないだけに、匿名の内部クラスは一度しか使用できません.通常、コードの作成を簡略化するために使用されます.
    匿名の内部クラスを使用する場合は、次の原則を覚えておきます.
  • 匿名の内部クラスには構造方法がありません.
  • 匿名の内部クラスは、静的メンバー、メソッド、およびクラスを定義できません.
  • 匿名の内部クラスはpublic、protected、private、staticではありません.
  • は匿名の内部クラスの1つのインスタンスしか作成できません.
  • 匿名の内部クラスは、newの後ろにあり、インタフェースを暗黙的に実装したり、クラスを実装したりするに違いない.
  • 匿名内部クラスはローカル内部クラスであるため、ローカル内部クラスのすべての制限が有効になります.

  • 「匿名の内部クラス」の存在意義について説明します.
    abstract class Person {
        public abstract void speak();
    }
     
    class Child extends Person {
        public void speak() {
            System.out.println("       !!");
        }
    }
     
    public class Demo {
        public static void main(String[] args) {
            Person p =new Child();
            p.speak();
        }
    }
    

    PersonクラスをChildで継承し,Childの一例を実現し,Personクラスの参照に上方転換したことが分かる.しかし,ここでChildクラスが一度しか使用されない場合,それを独立したクラスとして記述するのは面倒ではないか.
    このとき匿名の内部クラスが導入され、冗長なコードを簡略化するための意味があります.以下のようにします.
    abstract class Person {
        public abstract void speak();
    }
     
    public class Demo {
        public static void main(String[] args) {
            Person p =new Person() {
                public void speak() {
                    System.out.println("          ??");
                }
            };
            p.speak();
        }
    }
    

    こつこつ~~さっぱりしたのか、抽象的なPersonの方法をかっこで直接実現しました!
    実際には、抽象クラスまたはインタフェースであれば、そのサブクラスのメソッドは匿名の内部クラスを使用して実装することができ、最も一般的な場合は、マルチスレッドを実装するにはThreadクラスを継承するかRunnableインタフェースを継承する必要があるため、マルチスレッドの実装で実装することができます.
    よく使用される匿名の内部クラスの実装:
  • Threadクラスの匿名内部クラスは
  • を実現する.
    public class ThreadDemo {
        public static void main(String[] args) {
            Thread t =new Thread() {
                public void run() {
                    for(int i = 1; i <= 5; i++) {
                        System.out.print(i +",");
                    }
                }
            };
            t.start();
        }
    }
    //    :1,2,3,4,5,
    
  • Runnableインタフェースの匿名内部クラス実装
  • public class RunnableDemo {
        public static void main(String[] args) {
            Runnable r =new Runnable() {
                public void run() {
                    for(int i = 1; i <= 5; i++) {
                        System.out.print(i +" ");
                    }
                }
            };
            Thread t =new Thread(r);
            t.start();
        }
    }
    //    :1,2,3,4,5,
    

    小結
  • 「内部クラス」では、通常のクラスにアクセスできる属性を定義できます.これらの属性に重複名が発生した場合、アクセス限定修飾を行う必要があります.
  • はstaticキーワードで、トップクラスの内部クラスにアップグレードされ、普通のクラスと同じ特徴を備え、そっくりである.
  • メソッドで定義された内部クラスは、メソッドで定義されたfinalタイプのローカル変数にのみアクセスできます.
  • 匿名の内部クラスを使用するには、親クラスを継承するか、インタフェースを実装する必要があります.これは重要です!!

  • Javaクラウドノートはいつでもどこでも、最新で最も便利なクラウドサービスを提供します.