Java中的內部類

          1. 什么是內部類       

            內部類是指在一個外部類的內部再定義一個類。
            內部類可以是靜態static的,也可用public,default,protected和private修飾。(而外部頂級類即類名和文件名相同的只能使用public和default)。
            注意:內部類是一個編譯時的概念,一旦編譯成功,就會成為完全不同的兩類。對于一個名為Outer的外部類和其內部定義的名為Inner的內部類。編譯完成后出現Outer.class和Outer$Inner.class兩類。所以內部類的成員變量/方法名可以和外部類的相同。
            java內部類分為: 成員內部類、靜態嵌套類、局部內部類、匿名內部類 。

          2. 內部類的共性

            (1)、內部類仍然是一個獨立的類,在編譯之后內部類會被編譯成獨立的.class文件,但是前面冠以外部類的類名和$符號 。
            (2)、內部類不能用普通的方式訪問。內部類是外部類的一個成員,因此內部類可以自由地訪問外部類的成員變量,無論是否是private的 。
            (3)、內部類聲明成靜態的,就不能隨便的訪問外部類的成員變量了,此時內部類只能訪問外部類的靜態成員變量 。
          3. 成員內部類
            public class Outer {
                private int a = 10;
                private int b = 15;
                
                public void print() {
                    System.out.println("Outer.a="+this.a);
                }
                
                public int add(int i,int j) {
                    return i+j;
                }
                
                class Inner {        
                    private int a = 20;
                    private int c = b;
                    
                    public void print() {
                        //內部類訪問外部類中的同名成員變量
                        System.out.println("Outer.a="+Outer.this.a);    
                        System.out.println("Inner.a="+this.a);
                        System.out.println("a="+a);
                        //內部類中可以直接訪問外部類的成員變量和方法(內部類對象持有指向外部類對象的引用。)
                        System.out.println("c="+c);
                        System.out.println("c+1="+add(c,1));
                    }
                }
                
                public static void main(String[] args) {
                    Outer outer = new Outer();
                    outer.print();
                    //內部類對象的創建依賴于外部類對象;
                    outer.new Inner().print();   
                }
            }
            這個類編譯后出現Outer.class和Outer$Inner.class兩個class文件。編譯后成為兩個獨立的類,
            因此,內部類中可以定義與外部類中同名的屬性和方法。

            成員內部類,就是作為外部類的成員,與外部類的屬性、方法并列。可以直接使用外部類的所有成員和方法,即使是private的。
            同時外部類要訪問內部類的所有成員變量和方法,則需要通過內部類的對象來獲取。
            要注意的是,成員內部類不能含有static的變量和方法。因為成員內部類需要先創建了外部類,才能創建它自己的

          4. 局部內部類
            局部內部類,是指內部類定義在方法和作用域內。
            (1)、定義在方法內
                
            public class Teacher {
                
                private String name;
                private int age;    
                
                public void teach() {
                    final String str = "I'm a teacher!";
                    class EnglishTeacher {
                        public void teachEnglish() {
                            System.out.println("My name is "+name);
                            System.out.println("I'm "+age);
                            System.out.println(str);
                            System.out.println("I teach English");
                            
                        }
                    }
                    
                    EnglishTeacher englishTeacher = new EnglishTeacher();
                    englishTeacher.teachEnglish();
                }

                /**
                 * 
            @param args
                 
            */
                public static void main(String[] args) {
                    // TODO Auto-generated method stub
                    Teacher teacher = new Teacher();
                    teacher.name = "張三";
                    teacher.age = 35;
                    teacher.teach();
                }
            } 


            (2)、定義在作用域內
             

            public class Teacher1 {

                private String name;
                private int age;    
                
                public void teach(String course) {
                    final String str = "I'm a teacher!";
                    System.out.println(str);
                    if("English".equals(course)) {
                        class EnglishTeacher {
                            public void teachEnglish() {
                                System.out.println("My name is "+name);
                                System.out.println("I'm "+age);
                                System.out.println("I teach English");
                            }
                        }
                        
                        EnglishTeacher englishTeacher = new EnglishTeacher();
                        englishTeacher.teachEnglish();
                    }        
                }
                /**
                 * 
            @param args
                 
            */
                public static void main(String[] args) {
                    // TODO Auto-generated method stub
                    Teacher1 teacher = new Teacher1();
                    teacher.name = "張三";
                    teacher.age = 35;
                    teacher.teach("English");
                }

            }
                

            (1)、局部內部類只能在定義該內部類的方法內實例化,不可以在此方法外對其實例化。
            (2)、局部內部類對象不能使用該內部類所在方法的非final局部變量。
            (3)、局部內部類的地位和方法內的局部變量的位置類似,因此不能修飾局部變量的修飾符也不能修飾局部內部類,
                   譬如public、private、protected、static、transient等
            因為方法的局部變量位于棧上,只存在于該方法的生命期內。當一個方法結束,其棧結構被刪除,局部變量成為歷史。但是該方法結束之后,在方法內創建的內部類對象可能仍然存在于堆中!例如,如果對它的引用被傳遞到其他某些代碼,并存儲在一個成員變量內。正因為不能保證局部變量的存活期和方法內部類對象的一樣長,所以內部類對象不能使用它們。
          5. 靜態嵌套類


            public class StaticOuter {

                private int a = 10;
                private static int b = 15;
                
                static class StaticInner {
                    public static void print() {
                        System.out.println("b="+b);
                    }
                    
                    void print1() {
                        System.out.println("b="+b);
                    }
                }
                /**
                 * 
            @param args
                 
            */
                public static void main(String[] args) {
                    // TODO Auto-generated method stub
                    StaticOuter.StaticInner.print();
                    new StaticOuter.StaticInner().print1();
                }

            }

            嵌套類和普通的內部類還有一個區別:普通內部類不能有static數據和static屬性,也不能包含嵌套類,但嵌套類可以。
            而嵌套類不能聲明為private,一般聲明為public,方便調用。

            在靜態方法中定義的內部類也是StaticNested Class,這時候不能在類前面加static關鍵字,靜態方法中的StaticNested Class與
            普通方法中的內部類的應用方式很相似,它除了可以直接訪問外部類中的static的成員變量,還可以訪問靜態方法中的局部變量,
            但是,該局部變量前必須加final修飾符。

          6. 匿名內部類

          7. 匿名內部類就是沒有名字的內部類。什么情況下需要使用匿名內部類?如果滿足下面的一些條件,使用匿名內部類是比較合適的:
            ·只用到類的一個實例 。
            ·類在定義后馬上用到。
            ·類非常小(SUN推薦是在4行代碼以下)
            ·給類命名并不會導致你的代碼更容易被理解。
            在使用匿名內部類時,要記住以下幾個原則:
            ·匿名內部類不能有構造方法。
            ·匿名內部類不能定義任何靜態成員、靜態方法。
            ·匿名內部類不能是public,protected,private,static。
            ·只能創建匿名內部類的一個實例。
            ·一個匿名內部類一定是在new的后面,用其隱含實現一個接口或實現一個類。
            ·因匿名內部類為局部內部類,所以局部內部類的所有限制都對其生效。

            (1)、繼承式的匿名內部類

            public class Singer {
                
                public void sing() {
                    System.out.println("Sing a song");
                }

                /**
                 * 
            @param args
                 
            */
                public static void main(String[] args) {
                    // TODO Auto-generated method stub

                    Singer singer = new Singer() {

                        @Override
                        public void sing() {
                            // TODO Auto-generated method stub
                            System.out.println("Sing a popular song");
                        }
                        
                    };
                    singer.sing();
                }

            }

            輸出結果:Sing a popular song

            (2)、接口式的匿名內部類


            public interface Programmer {
                
                public void code();

            }



            public class TestProgrammer {

                /**
                 * 
            @param args
                 
            */
                public static void main(String[] args) {
                    // TODO Auto-generated method stub
                    Programmer javaProgrammer = new Programmer() {

                        @Override
                        public void code() {
                            // TODO Auto-generated method stub
                            System.out.println("Java programmer");
                        }
                    };

                    javaProgrammer.code();
                    
                    Programmer phpProgrammer = new Programmer() {

                        @Override
                        public void code() {
                            // TODO Auto-generated method stub
                            System.out.println("Php programmer");
                        }
                    };

                    phpProgrammer.code();
                }

            }

            (3)、參數式的匿名內部類


            public interface Programmer {
                
                public void code();

            }




            public class TestProgrammer1 {

                public void testCode(Programmer p) {
                    p.code();
                }
                
                /**
                 * 
            @param args
                 
            */
                public static void main(String[] args) {
                    // TODO Auto-generated method stub
                    TestProgrammer1 testProgrammer1 = new TestProgrammer1();
                    testProgrammer1.testCode(new Programmer() {
                        
                        @Override
                        public void code() {
                            // TODO Auto-generated method stub
                            System.out.println("testing code");
                        }
                    });
                }

            }


          8. 為什么需要內部類

          9. 典型的情況是,內部類繼承自某個類或實現某個接口,內部類的代碼操作創建其的外圍類的對象。所以你可以認為內部類提供了某種進入其外圍類的窗口。
            使用內部類最吸引人的原因是:
            每個內部類都能獨立地繼承自一個(接口的)實現,所以無論外圍類是否已經繼承了某個(接口的)實現,對于內部類都沒有影響。如果沒有內部類提供的可以繼承多個具體的或抽象的類的能力,一些設計與編程問題就很難解決。從這個角度看,內部類使得多重繼承的解決方案變得完整。接口解決了部分問題,而內部類有效地實現了“多重繼承”。

          posted on 2014-08-01 17:34 小羅 閱讀(201) 評論(0)  編輯  收藏


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          <2025年5月>
          27282930123
          45678910
          11121314151617
          18192021222324
          25262728293031
          1234567

          導航

          統計

          常用鏈接

          留言簿

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          相冊

          收藏夾

          Web Framework

          常上的技術網站

          查找資料的java網站

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 蒲城县| 泗阳县| 平塘县| 青河县| 微山县| 南华县| 汶川县| 南充市| 海盐县| 南昌市| 南涧| 兴文县| 塔河县| 文化| 当阳市| 海城市| 页游| 通榆县| 常德市| 宣化县| 阜新市| 四会市| 西城区| 锡林郭勒盟| 波密县| 林口县| 顺昌县| 张家界市| 册亨县| 青海省| 焉耆| 东光县| 方正县| 崇明县| 濮阳县| 兴和县| 彰化市| 玉溪市| 翁源县| 东丰县| 南川市|