內部類的詳細解釋和用法

內部類的詳細解釋和用法


內部類 其實並不是什麼地方都能用上,但是我們爲什麼還要學習它呢,下面我們從語法和作用上去慢慢的瞭解他們
語法:  類中定義類
        class A{
                class B{ /*
                                  可能在剛開始學習類的時候也這樣寫過,當時可能是沒有注意縮進格式
                                   B就是A的內部類   編譯之後會生成兩個class文件  A.class    A$B.class  說明內部類只是在編譯期有效
                                   到運行期 A和B是沒有包含關係 是兩個相互獨立的類  所以內部類僅僅是一個編譯期的語法
                                  */
                }
        }
分類 ---
   成員內部類   和成員屬性定義位置一樣  可以訪問外部類的私有成員,創建成員內部類必須先創建外部類對象,
                語法:   外部類對象.new  內部類對象();
                                成員內部類中不能有靜態成員
                                如果在內部類定義和外部類同名屬性 在內部類調用的時候用 外部類.this.屬性名  -->外部類.this 指向外部類的當前對象
                                public class 內部類 {
                                        public static void main(String[] args) {
                                                 //我想在主方法中創建一個inner對象調用打印方法
                                                 // Outer.Inner in=new Outer.Inner();
                                                 // in.print();
                                                 /*
                                                        a是outer裏邊的私有屬性整個屬性是什麼時候創建的 ?-->是在Outer創建對象的時候纔有的  你現在沒有創建對象呢
                                                        a是不存在的能進行打印嗎,
                                                        由於成員內部類能訪問外部類的私有屬性,這句話潛意識的就是在說 你的先創建一個外部類對象 然後通過外部類對象
                                                        創建內部類對象
                                                  */
                                                   Outer  o1=new Outer(100);
                                                   Outer  o2=new Outer(200);
                                                   Outer.Inner in = o2.new Inner(); //語法有點奇怪
                                                   in.print();
                                                   //如果我給內部定義靜態屬性

                                                   // 在內部類定義和外部類同名屬性
                                                   //調用  System.out.println(Outer.this.a);
                                        }
                                }
                                class Outer{
                                        private int a=100;
                                        public  Outer(int a){
                                                this.a=a;
                                        }
                                        class Inner{//這個inner就是outer類的成員內部類  它的定義位置是Outer類的成員位置上  可以用private  public修飾
                                                //裏邊和正常定義類一樣
                                                int  a=20;
                                                public void print(){
                                                        /*
                                                           那能不能打印a   a的作用範圍是整個Outer類  所以是可以打印的  inner在Outer類的封裝範圍內
                                                         */
                                                        System.out.println(a);
                                                        System.out.println(Outer.this.a);
                                                }
                                                //static int b=10;  //內部類不能有靜態成員
                                        }
                                }
   靜態內部類   和靜態成員定義位置一樣  靜態內部類只能訪問外部類的靜態成員  所以不再需要先創建外部類對象
                語法:  new 外部類.內部類
                                public class 內部類 {
                                        public static void main(String[] args) {
                                                Outer.Inner inner = new Outer.Inner();
                                                inner.print();
                                        }
                                }
                                class  Outer{
                                         private int a=10;
                                         private static int  b=20;
                                         static class Inner{
                                                 public void print(){
                                                         System.out.println(a);//靜態內部類只能訪問外部類的靜態成員
                                                         System.out.println(b);
                                                 }
                                         }
                                }
                                
                                
                                
   局部內部類   使用範圍等同於局部變量  局部內部類不僅可以訪問外部類的私有成員 還可以訪問外部類的局部變量  
                被內部類訪問的局部變量會被拷貝一份到內部類中,即Inner中存在一個成員變量,用於記錄局部變量a的值。
                                若局部變量不是final的,其取值就可以被修改,而Inner對象中保存的是其原來的值,這就會出現數據不同步的問題。
                Java爲了避免數據不同步的問題,做出了內部類只可以訪問final的局部變量的限制。
                                在java8中,可以不使用final,如果局部變量被內部類訪問,那麼該局部變量相當於自動使用了final修飾。
                public class 內部類 {
                                        public static void main(String[] args) {
                                                Outer out=new Outer();
                                                out.method(10);
                                        }
                                }
                                class  Outer{
                                         private int a=10;
                                         public  void method(int  b){
                                                 int c=20;
                                                 class Inner{//作用範圍就是method方法內部
                                                         public void print(){//我想調用這個方法怎麼弄  只能抓緊在method方法內部做  出了這個方法就不能用了
                                                                 System.out.println("hehe");
                                                                 System.out.println(a);
                                                                 System.out.println(b);
                                                                 System.out.println(c);
                                                         }
                                                 }
                                                 Inner  in=new Inner();
                                                 in.print();
                                         }
                                }

    匿名內部類:   
               1)特殊的局部內部類        
                           2)繼承一個類或者是實現一個接口
                           3)只會創建該類的一個對象
                           4)只能用默認的構造方法
                           class School{
                                        public  static  Teacher  getTeacher(int i){
                                           /* class  CangTeacher implements Teacher{
                                                        public  void Teacher(){
                                                                System.out.println("Cang teachers");
                                                        }
                                                }
                                                class DaTeacher implements Teacher{
                                                        public  void Teacher(){
                                                                System.out.println("Da teachers");
                                                        }
                                                }
                                                if(i%2==0)return  new CangTeacher();
                                                else return new DaTeacher();*/
                                                if(i%2==0)return  new Teacher() {
                                                        @Override
                                                        public void Teacher() {
                                                                System.out.println("蒼老師teacher");
                                                        }
                                                } ;
                                                else return new Teacher() {

                                                        @Override
                                                        public void Teacher() {
                                                                System.out.println("大老師講課");
                                                        }
                                                };
                                                /*
                                                  無論是蒼老師 還是大老師 我都只創建了一次  所以當三個條件滿足之後 我就能把這個局部內部類改造成爲匿名內部類
                                                  改造方式
                                                  new  接口(){
                                                         實現這個接口中的方法
                                                  }
                                                  其實我要new的不是接口  我需要的是一個對象把接口實現了 {} 這就是一個類的隱含的實現接口, 這個類叫什麼不知道
                                                  匿名內部類是把  定義類,實現接口 new對象和在一起了
                                                  其實匿名內部了類的語法完全可以用局部內部類代替    匿名代碼少寫一行 丟掉的是程序的可讀性
                                                  它的應用很廣泛 很多程序員都在使用,
                                                  可以讓人在編程的時候思路不斷

                                                  匿名內部類能定義構造方法嗎?  沒名字不能
                                                 */
                                        }

                                }
                                interface Teacher{
                                        public  void Teacher();
                                }

內部類是一個編譯期的語法 在運行的時候是兩個獨立的類 那爲什麼還要讓一個類成爲另一個類的內部類
1  內部類可以訪問外部類的私有成員而不破壞封裝  
2  接口公開  接口的實現類作爲內部類隱藏起來 強制弱耦合
    public class 內部類 {
                public static void main(String[] args) {
                        //學生寫的主方法  我們這樣設計希望 學生這樣寫代碼   它和老師之間是弱耦合的  如果換個老師是對學生之間是沒有影響的
                        //只要學校去改動getTeacher()代碼
                        Teacher t = School.getTeacher(0);
                        t.Teacher();
                        //但是學生還可以這樣寫
                        CangTeacher  c=new CangTeacher();
                        c.Teacher();
                        /*
                          上邊也是調用蒼老師的方法  下邊也是調用蒼老師的方法   但是如果把代碼寫成下面的樣子我們的一番苦心就白費了
                          上來繞開接口和學校,直接找了蒼老師  ---->這是可以的,但是我們利用接口實現弱耦合辦不到了,
                          這事情如果是學生們都要求蒼老師講課程,學校就應該着急了,
                          所以爲了杜絕學生這樣寫代碼
                          需要從新改造
                          把兩個老師 只能在學校的getTeacher()中使用, 所以把這兩個做成局部內部類   只能學校使用,
                          站在學生角度只能看到 老師接口  還有學校
                         */
                }
        }
        /*class  CangTeacher implements Teacher{
                public  void Teacher(){
                        System.out.println("Cang teachers");
                }
        }
        class DaTeacher implements Teacher{
                public  void Teacher(){
                        System.out.println("Da teachers");
                }
        }*/
        class School{ //
                public  static  Teacher  getTeacher(int i){
                        class  CangTeacher implements Teacher{
                                public  void Teacher(){
                                        System.out.println("Cang teachers");
                                }
                        }
                        class DaTeacher implements Teacher{
                                public  void Teacher(){
                                        System.out.println("Da teachers");
                                }
                        }
                        if(i%2==0)return  new CangTeacher();
                        else return new DaTeacher();
                }

        }
        interface Teacher{
                public  void Teacher();
        }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章