Rumah  >  Artikel  >  Java  >  Analisis contoh kelas dalaman Java

Analisis contoh kelas dalaman Java

WBOY
WBOYke hadapan
2023-04-23 14:43:14526semak imbas

    1 Konsep dan klasifikasi kelas dalaman

    Apabila kelas ditakrifkan di dalam kelas lain atau di dalam antara muka atau di dalam badan kaedah, kelas ini ialah Ia dipanggil kelas dalam Kita juga boleh memanggil kelas di mana kelas dalam terletak sebagai kelas persisian Selain daripada kelas dalaman yang ditakrifkan dalam kelas, antara muka dan kaedah, terdapat juga kelas dalaman khas, iaitu untuk. gunakan kata kunci baharu untuk mencipta kelas tanpa nama, dan kelas tanpa nama ini sebenarnya ialah kelas dalaman, khususnya kelas dalaman tanpa nama, yang sering digunakan untuk membina objek dengan menghantar argumen pembina, seperti penciptaan objek PriorityQueue.

    Apabila kelas ditakrifkan di dalam kelas lain atau di dalam antara muka, dan tiada pengubahsuaian statik, kelas dalaman dipanggil kelas dalaman contoh Apabila pengubahsuaian statik digunakan, kelas dalaman dipanggil dalaman statik class ( Kelas bersarang), tentukan kelas di dalam blok kod, terutamanya di dalam badan kaedah ini dipanggil kelas dalaman tempatan atau kelas dalaman tempatan, dan yang lain ialah kelas dalaman tanpa nama yang disebutkan di atas.

    2. Kelas dalam contoh

    2.1 Penciptaan kelas dalam contoh

    Takrifan kelas dalam contoh adalah sangat mudah, hanya tentukan ia terus di dalam kelas luar. Persoalannya ialah bagaimana untuk mencipta objek kelas dalam Pertama sekali, anda perlu memahami bahawa pembolehubah ahli dan kaedah dalam kelas dalam dan kelas luar berada pada kedudukan yang sama Mereka semua tergolong dalam objek kelas luar (tanpa statik pengubahsuaian), jadi jika anda mahukan objek kelas dalam, anda mesti terlebih dahulu mempunyai objek kelas Periferal, cara pertama untuk mencipta objek kelas dalam ialah menggunakan kaedah untuk mengembalikan objek kelas dalam, dan jenis objek kelas dalam ini ialah OutClassName.InnerClassName, iaitu nama kelas luar.nama kelas dalam.

    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 Menggunakan .this and .new

    Sudah tentu, terdapat cara lain untuk mencipta kelas dalam, iaitu menggunakan objek kelas luar .baru untuk mencipta Objek kelas dalam, sintaksnya ialah:

    Objek kelas luar.kaedah pembinaan kelas dalaman baharu Untuk memaut dengan kelas luar, pertama sekali, penciptaan objek kelas dalam contoh bergantung pada rujukan objek kelas luar Pembolehubah ahli kelas dalam dan kelas luar mempunyai status yang sama Jika anda ingin mengakses pembolehubah ahli dan kaedah kelas luar melalui objek kelas dalam (terutama pembolehubah dengan. nama yang sama). Dalam kelas dalam, anda boleh menggunakan nama kelas luar. ini untuk mendapatkan objek kelas luar, dan kemudian gunakan objek kelas luar yang diperoleh untuk menggunakan pembolehubah dan kaedah kelas luar.

    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
    Sebenarnya, terdapat dua ini dalam objek kelas dalam Secara langsung menggunakan ini untuk mendapatkan ahli objek kelas dalam sendiri, dan menggunakan nama kelas luar dapatkan di atas Ia adalah ahli kelas luar, iaitu, dalam kelas dalam, ini menunjukkan rujukan objek kelas dalam itu sendiri, dan nama kelas luar. ini menunjukkan rujukan objek kelas luar .

    Apabila nama pembolehubah kelas dalam dan kelas luar mempunyai nama yang sama, kedua-dua nama ini sangat berguna.
    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

    Jika nama yang sama tidak muncul, dapatkan ahli secara langsung Anda tidak perlu menggunakan ini seperti yang dinyatakan di atas Jika nama yang sama muncul, ahli yang diakses secara terus objek kelas dalam secara lalai.

    2.3 Kelas dalam melaksanakan pencetakan berulang
    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
    Kelas dalam boleh mempunyai akses kepada semua elemen kelas luar, jadi kita boleh cuba menggunakan kelas dalam untuk melintasi dan mengeluarkan elemen dalam kelas luar , walaupun kelas dalam Status ahli kelas luar adalah sama, tetapi kelas dalam juga merupakan kelas ia juga boleh mewarisi kelas dan melaksanakan antara muka seperti kelas luar.

    2.4 Pewarisan kelas dalam

    Pewarisan kelas dalam agak menyusahkan, kerana pembina kelas dalam mesti bergantung pada rujukan kelas luar, jadi sintaks khas diperlukan Untuk menggambarkan hubungan antara kelas dalaman dan kelas persisian:
    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

    Rujukan kelas persisian.super();

    Untuk arahan khusus, lihat kod berikut :

    Apabila kelas dalam diwarisi, ia perlu menghantar rujukan kelas luar ke dalam pembina kelas induk dan memanggil super() untuk lulus kompilasi.

    Jika kelas dalam mewarisi kelas luar, ia boleh diwarisi terus tanpa banyak masalah.

    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);
            
        }
    }
    Apabila program menjana fail bytecode bagi fail java, ia dinamakan kelas luaran awam $ kelas dalaman.

    Kelas dalaman boleh bersarang tanpa had, tetapi secara amnya tiada sesiapa yang melakukan ini.

    3. Kelas dalaman statik

    Kelas dalaman statik juga dipanggil kelas bersarang Ia adalah untuk menambah kata kunci statik sebelum takrifan kelas dalam contoh, seperti berikut:

    <.>

    Perbezaan dari kelas dalaman adalah kelas dalaman statik tergolong dalam kelas dan bukannya objek. .

    4. Kelas dalaman Tanpa Nama
    public class Outer {
        
        static class Inner{
            
        }
    }

    Kami telah pun melihat penggunaan kelas dalaman tanpa nama, iaitu, apabila mencipta objek PriorityQueue, timbunan kecil dicipta secara lalai dan perlu dihantar dalam pembanding untuk membuat timbunan besar.

    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);
        }
    }
    //output:
    我是静态内部类!
    
    Process finished with exit code 0
    Seperti kaedah di atas, gunakan kata kunci baharu untuk mencipta objek kelas tanpa nama sebagai parameter sebenar Kelas tanpa nama di dalam ialah objek kelas tanpa nama Comparator dalam proses penciptaan diwarisi . Jenis parameter yang perlu diluluskan ialah kelas Comparator di sini.

    Jika anda menggunakan jenis tersuai untuk masuk ke baris gilir keutamaan, anda mesti melaksanakan pembanding Cara paling biasa untuk melaksanakan pembanding ialah kelas dalam tanpa nama dan ungkapan Lambda.

    假设我有一个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{
                //
            }
        }
    }

    Atas ialah kandungan terperinci Analisis contoh kelas dalaman Java. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

    Kenyataan:
    Artikel ini dikembalikan pada:yisu.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam