Java内部クラスのサンプル分析

WBOY
リリース: 2023-04-23 14:43:14
転載
571 人が閲覧しました

    1. 内部クラスの概念と分類

    クラスが別のクラス内、インターフェイス内、またはメソッド本体内で定義されている場合、このクラスはこれは内部クラスと呼ばれます。内部クラスが配置されているクラスを周辺クラスと呼ぶこともできます。クラス、インターフェイス、メソッドで定義された内部クラスに加えて、特別な内部クラスもあります。キーワード new を使用して匿名クラス Object を作成し、この匿名クラスは実際には内部クラス、具体的には匿名内部クラスであり、PriorityQueue オブジェクトの作成など、コンストラクター引数を渡すことによってオブジェクトを構築するためによく使用されます。

    クラスが別のクラス内またはインターフェイス内で定義され、静的な変更がない場合、内部クラスはインスタンス内部クラスと呼ばれ、静的な変更が使用される場合、内部クラスは静的内部クラスと呼ばれますクラス (ネストされたクラス) では、コード ブロック内、特にメソッド本体内にクラスを定義します。この内部クラスはローカル内部クラスまたはローカル内部クラスと呼ばれ、もう 1 つは上記の匿名内部クラスです。

    2. インスタンス内部クラス

    2.1 インスタンス内部クラスの作成

    インスタンス内部クラスの定義は非常に簡単で、外部クラス内に直接定義するだけです。問題は、内部クラスのオブジェクトをどのように作成するかです。まず、内部クラスと外部クラスのメンバー変数とメソッドは同等の立場にあることを理解する必要があります。それらはすべて外部クラスのオブジェクトに属します (静的オブジェクトは含まれません)。変更)、そのため、内部クラス オブジェクトが必要な場合は、まず Peripheral クラス オブジェクトが必要です。内部クラス オブジェクトを作成する最初の方法は、内部クラス オブジェクトを返すメソッドを使用することです。この内部クラス オブジェクトの型は次のとおりです。 OutClassName.InnerClassName、つまり、外部クラス名.内部クラス名。

    public class Outer {
    
        class Inner1 {
            private String str;
            public Inner1(String s) {
                this.str = s;
            }
            public String readStr() {
                return this.str;
            }
        }
    
        class Inner2 {
            private int val;
            public Inner2(int i) {
                this.val = i;
            }
            public int readVal() {
                return this.val;
            }
        }
        //创建内部类
        public Inner1 creatInner1(String s) {
            return new Inner1(s);
        }
        public Inner2 creatInner2(int i) {
            return new Inner2(i);
        }
    
        public static void main(String[] args) {
            Outer outer = new Outer();
            Outer.Inner1 inner1 =  outer.creatInner1("Inner1");
            Outer.Inner2 inner2 = outer.creatInner2(2);
    
            System.out.println(inner1.readStr());
            System.out.println(inner2.readVal());
        }
    }
    ログイン後にコピー
    //output:
    Inner1
    2
    
    Process finished with exit code 0
    ログイン後にコピー
    ログイン後にコピー

    2.2 .this と .new

    を使用する もちろん、内部クラスを作成する他の方法もあります。それは、外部クラス .new のオブジェクトを使用して内部クラスを作成することです。構文は次のとおりです:

    外部クラス オブジェクト.新しい内部クラス構築メソッド;

    public class Outer {
    
        class Inner1 {
            private String str;
            public Inner1(String s) {
                this.str = s;
            }
            public String readStr() {
                return this.str;
            }
        }
    
        class Inner2 {
            private int val;
            public Inner2(int i) {
                this.val = i;
            }
            public int readVal() {
                return this.val;
            }
        }
    
    
        public static void main(String[] args) {
            Outer outer = new Outer();
            Outer.Inner1 inner1 =  outer.new Inner1("Inner1");
            Outer.Inner2 inner2 = outer.new Inner2(2);
    
            System.out.println(inner1.readStr());
            System.out.println(inner2.readVal());
        }
    }
    ログイン後にコピー
    //output:
    Inner1
    2
    
    Process finished with exit code 0
    ログイン後にコピー
    ログイン後にコピー

    内部クラスの特徴はそれだけではありません。内部クラスは次のようにすることもできます。周辺クラスとリンクする まず、内部クラスのオブジェクトをインスタンス化します 外部クラスのオブジェクトの参照を利用して作成します インスタンスの内部クラスと外部クラスのメンバ変数は同じ状態になります メンバ変数と外部クラスにアクセスしたい場合内部クラスのオブジェクトを介して、外部クラスのメソッド (特に同じ名前の変数) を呼び出します。内部クラスでは、外部クラス名.this を使用して外部クラス オブジェクトを取得し、取得した外部クラス オブジェクトを使用して外部クラスの変数とメソッドを使用できます。

    public class Outer {
        private String outStr;
        public Outer(String str) {
            this.outStr = str;
        }
    
        public void printOuter() {
            System.out.println(this.outStr);
        }
    
        class Inner {
            private String str;
            public Inner(String s) {
                this.str = s;
            }
            public String readStr() {
                return this.str;
            }
            //使用.this获取父类对象引用
            public Outer outer() {
                return Outer.this;
            }
        }
    
    
    
        public static void main(String[] args) {
            Outer outer = new Outer("outerString");
            Outer.Inner inner = outer.new Inner("innerString");
    
            Outer out = inner.outer();
            out.printOuter();
        }
    }
    ログイン後にコピー
    //output:
    outerString
    
    Process finished with exit code 0
    ログイン後にコピー

    実際、内部クラス オブジェクトには this が 2 つあり、this. member を直接使用すると内部クラス オブジェクト自体のメンバーが取得され、上記のように外部クラスの name.this. member を使用すると内部クラス オブジェクト自体のメンバーが取得されます。外部クラスのメンバー、つまり内部クラスでは、this は内部クラス オブジェクト自体の参照を指し、外部クラス name.this は外部クラス オブジェクトの参照を指します。

    内部クラスと外部クラスの変数名が同じ名前である場合、これら 2 つは非常に役立ちます。

    public class Outer {
        public int a = 12;
        public int b = 16;
        public int c = 20;
    
        class Inner{
            public int a = 8;
            public int c = 48;
            public int d = 2;
    
            public void printVal() {
                System.out.println("外围类变量a=" + Outer.this.a);
                System.out.println("外围类变量b=" + Outer.this.b);
                System.out.println("外围类变量c=" + Outer.this.c);
                System.out.println("内部类变量a=" + this.a);
                System.out.println("内部类变量c=" + this.c);
                System.out.println("内部类变量d=" + this.d);
            }
        }
    
        public Inner creatInner() {
            return new Inner();
        }
    
        public static void main(String[] args) {
            Outer outer = new Outer();
    
            Outer.Inner inner = outer.creatInner();
            inner.printVal();
        }
    }
    ログイン後にコピー
    //output:
    外围类变量a=12
    外围类变量b=16
    外围类变量c=20
    内部类变量a=8
    内部类变量c=48
    内部类变量d=2
    
    Process finished with exit code 0
    ログイン後にコピー

    同じ名前が表示されない場合は、メンバーを直接取得してください。上記のようにこれを使用する必要はありません。同じ名前が表示された場合、直接アクセスされるメンバーはデフォルトで内部クラス オブジェクトになります。

    2.3 内部クラスは反復印刷を実装します

    内部クラスは外部クラスのすべての要素にアクセスできるため、内部クラスを使用して外部クラスの要素を走査して出力することができます。内部クラスであっても外部クラスのメンバーのステータスは同等ですが、内部クラスも結局はクラスであり、外部クラスと同様にクラスを継承したりインターフェースを実装したりすることもできます。

    import java.util.Arrays;
    
    interface Selector{
        //判断是否迭代完全部元素
        public boolean end();
        //获取当前元素
        public Object current();
        //迭代下一个元素
        public void next();
    }
    
    public class SequeArray {
        private Object[] items;
        private int usedSize;
    
        public SequeArray(int capacity) {
            items = new Object[capacity];
        }
        public void add(Object val) {
            if (usedSize == items.length) items = Arrays.copyOf(items, 2 * usedSize);
    
            items[usedSize++] = val;
        }
    
        private class SequeSelector implements Selector{
            private int index;
    
            public boolean end() {
                return index == usedSize;
            }
            public Object current() {
                return items[index];
            }
            public void next() {
                if (index < usedSize) index++;
            }
        }
        public SequeSelector sequeSelector() {
            return new SequeSelector();
        }
    
        public static void main(String[] args) {
            SequeArray array = new SequeArray(10);
    
            for (int i = 0; i < 10; i++) {
                array.add(i+1);
            }
            //发生了向上转型
            Selector selector = array.sequeSelector();
    
            while (!selector.end()) {
                System.out.print(selector.current() + "   ");
                selector.next();
            }
        }
    }
    ログイン後にコピー
    //output:
    1   2   3   4   5   6   7   8   9   10   
    Process finished with exit code 0
    ログイン後にコピー

    2.4 内部クラスの継承

    内部クラスの継承は少し面倒です。内部クラスのコンストラクターは外部クラスの参照に依存する必要があるため、特別な構文が必要です。内部クラスと周辺クラスの関連付けの関係を説明するには:

    Peripheral classreference.super();

    具体的な使用方法については、以下を参照してください。 code:

    public class Outer {
        class Inner{
            
        }
    }
    class Person extends Outer.Inner {
        private String str;
        private int id;
        public Person(Outer out, String str, int id) {
            out.super();
            this.str = str;
            this.id = id;
        }
        public void readVal() {
            System.out.println(this.str + this.id);
            
        }
    }
    ログイン後にコピー

    内部クラスが次の場合 継承する場合は、親クラスのコンストラクタに周辺クラスの参照を渡し、super()を呼び出してコンパイルを通す必要があります。

    内部クラスが外部クラスを継承する場合は、直接継承するだけで問題ありません。

    プログラムが Java ファイルのバイトコード ファイルを生成するときは、そのファイルに public external class $internal class という名前を付けます。

    内部クラスは無限にネストできますが、通常はこれを行う人はいません。

    3. 静的内部クラス

    静的内部クラスはネストされたクラスとも呼ばれ、次のようにインスタンス内部クラスの定義の前に静的キーワードを追加します。

    インスタンス内部クラスとの違いは、静的内部クラスがオブジェクトではなくクラスに属するため、静的内部クラスの作成が外部クラスのオブジェクトに依存しない点であり、これがインスタンス内部クラスとの最大の違いの 1 つです。

    public class Outer {
        
        static class Inner{
            
        }
    }
    ログイン後にコピー
    public class Outer {
        static class Inner{
            private String str;
            public Inner(String s) {
                str = s;
            }
        }
    
        public static void main(String[] args) {
            Outer.Inner inner = new Outer.Inner("我是静态内部类!");
            System.out.println(inner.str);
        }
    }
    ログイン後にコピー

    4. 匿名内部クラス

    匿名内部クラスの使用法についてはすでに見てきました。つまり、PriorityQueue オブジェクトを作成するときに、デフォルトで小さなヒープが作成され、コンパレータが必要になります。大きなヒープを作成するために渡されます。

    //output:
    我是静态内部类!
    
    Process finished with exit code 0
    ログイン後にコピー

    上記と同様に new キーワードを使用して匿名クラスのオブジェクトを実引数として作成します 内部の匿名クラスは匿名内部クラスです 作成過程の Comparator 匿名クラス オブジェクトは1 つは継承によって渡されます。パラメータのタイプ。これは Comparator クラスです。

    カスタム タイプを使用して優先キューに渡す場合は、コンパレータを実装する必要があります。コンパレータを実装する最も一般的な方法は、匿名の内部クラスとラムダ式です。

    假设我有一个Person类数组,需要对他们的name排序,如果不使用内部类,就需要在Person类中实现比较器。

    import java.util.Arrays;
    import java.util.Comparator;
    
    class Preson {
        public String name;
        public Integer id;
        public Preson(String name, Integer id) {
            this.name = name;
            this.id = id;
        }
    
        @Override
        public String toString() {
            return "Preson{" +
                    "name=&#39;" + name + &#39;\&#39;&#39; +
                    ", id=" + id +
                    &#39;}&#39;;
        }
    }
    class PersonComparator implements Comparator<Preson> {
        @Override
        public int compare(Preson o1, Preson o2) {
            return o1.name.compareTo(o2.name);
        }
    }
    public class Main {
        public static void main(String[] args) {
            Preson preson1 = new Preson("aboluo", 24);
            Preson preson2 = new Preson("zhousi", 25);
            Preson preson3 = new Preson("syyfjy", 2);
            Preson[] presons = {preson1, preson2, preson3};
            Arrays.parallelSort(presons, new PersonComparator());
            System.out.println(Arrays.toString(presons));
        }
    }
    ログイン後にコピー
    //output:
    [Preson{name=&#39;aboluo&#39;, id=24}, Preson{name=&#39;syyfjy&#39;, id=2}, Preson{name=&#39;zhousi&#39;, id=25}]
    
    Process finished with exit code 0
    ログイン後にコピー
    ログイン後にコピー

    使用内部类上述代码就变为:

    import java.util.Arrays;
    import java.util.Comparator;
    
    class Preson {
        public String name;
        public Integer id;
        public Preson(String name, Integer id) {
            this.name = name;
            this.id = id;
        }
    
    
        @Override
        public String toString() {
            return "Preson{" +
                    "name=&#39;" + name + &#39;\&#39;&#39; +
                    ", id=" + id +
                    &#39;}&#39;;
        }
    }
    
    public class Main {
        public static void main(String[] args) {
            Preson preson1 = new Preson("aboluo", 24);
            Preson preson2 = new Preson("zhousi", 25);
            Preson preson3 = new Preson("syyfjy", 2);
            Preson[] presons = {preson1, preson2, preson3};
            Arrays.parallelSort(presons, new Comparator<Preson>() {
                @Override
                public int compare(Preson o1, Preson o2) {
                    return o1.name.compareTo(o2.name);
                }
            });
            System.out.println(Arrays.toString(presons));
        }
    }
    ログイン後にコピー
    //output:
    [Preson{name=&#39;aboluo&#39;, id=24}, Preson{name=&#39;syyfjy&#39;, id=2}, Preson{name=&#39;zhousi&#39;, id=25}]
    
    Process finished with exit code 0
    ログイン後にコピー
    ログイン後にコピー

    还有一个本地内部类,就是类定义在方法中,就不多说了,基本上不用,用法如下:

    public class Outer {
        public void func() {
            class Inner{
                //
            }
        }
    }
    ログイン後にコピー

    以上がJava内部クラスのサンプル分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

    関連ラベル:
    ソース:yisu.com
    このウェブサイトの声明
    この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
    人気のチュートリアル
    詳細>
    最新のダウンロード
    詳細>
    ウェブエフェクト
    公式サイト
    サイト素材
    フロントエンドテンプレート