靜態嵌套類(Static Nested Class)和內部類(Inner Class)的區別

可以在一個類的內部定義另一個類, 這種類稱爲嵌套類(nested classes),它有兩種類型: 
靜態嵌套類和非靜態嵌套類.靜態嵌套類使用很少, 最重要的是非靜態嵌套類, 也即是被稱作爲
內部類(inner).嵌套類從JDK1.1開始引入.其中inner類又可分爲三種: 
(1) 在一個類(外部類)中直接定義的內部類;
(2) 在一個方法(外部類的方法)中定義的內部類;
(3) 匿名內部類.

一、什麼是靜態嵌套類?
直接在外部類裏面定義的靜態類

public class StaticTest
{
   private static String name = "gugu";
   private String num = "001";

   static class Person //靜態嵌套類
   {
     private String address = "China";
     public String mail = "xxxxxx.com";//內部類公有成員

     public void display()
     {
       //System.out.println(num);//不能直接訪問外部類的非靜態成員
       System.out.println(name);//只能直接訪問外部類的靜態成員
       System.out.println("Inner " + address);//訪問本內部類成員。
     }
   }

   public void printInfo()
   {
     Person person = new Person();
     person.display();

     //System.out.println(mail);//不可訪問
     //System.out.println(address);//不可訪問

     System.out.println(person.address);//可以訪問內部類的私有成員
     System.out.println(person.mail);//可以訪問內部類的公有成員

   }

   public static void main(String[] args)
   {
     StaticTest staticTest = new StaticTest();
     staticTest.printInfo();
   }
}

1.在靜態嵌套類內部, 不能訪問外部類的非靜態成員, 這是由Java語法中"靜態方法不能直接訪問非靜態成員"所限定.若想訪問外部類的變量, 必須通過其它方法解決, 由於這個原因, 靜態嵌套類使用很少.
2.外部類訪問內部類的的成員有些特別, 不能直接訪問, 但可以通過內部類實例來訪問, 這是因爲靜態嵌套內的所有成員和方法默認爲靜態的了.同時注意, 內部靜態類Person只在類StaticTest 範圍內可見, 若在其它類中引用或初始化, 均是錯誤的.

二、什麼是內部類?

內部類分爲①定義在外部類的內部類②定義在方法裏面的內部類③匿名內部類

特點:內部類可以直接訪問外部類的成員,包括私有
外部類要訪問內部類的成員,必須創建對象

1.內部類生成外部的引用  外部類名.this
2.局部內部類只能在其所在的方法內訪問
3.成員內部類私有 paivate, 其他類調用不能直接創建對象(類似私有成員變量),在外部類寫一個方法,訪問,類似於setXX,getXX訪問私有成員,且只在外部類的範圍內可見

(一)定義在外部類的內部類


class Outer {

    public String outer__public_name = "外部類public";
    private String outer_private_name = "外部類private";
    public int a =100;
    private class InnerOne  // 私有的內部類 起
    {
        public String innerone_public_name = "內部類1public";
        private String innerone_private_name = "內部類1private";

        public void display() {
            System.out.println(" Outer_outer__public_name:" + outer__public_name);
            System.out.println(Outer.this.a);

        }

        private void display2() {
            System.out.println(" Outer_outer_private_name:" + outer_private_name);
        }

    }// 私有的內部類 止

    public InnerOne getInnerOne() {
        // 即使是對外公開的方法,外部類也無法調用
        return new InnerOne();
    }

    class InnerTwo //內部類 起
    {
        InnerOne innerx = getInnerOne();// 可以訪問

        public void show() {
            //System.out.println(innerone_public_name); // 不可訪問Innter的y成員
            //System.out.println(innerone_private_name);   // 不可直接訪問Inner的任何成員和方法
            innerx.display();// 可以訪問
            innerx.display2();// 可以訪問
            System.out.println(innerx.innerone_public_name);// 可以訪問
            System.out.println(innerx.innerone_private_name);// 可以訪問
        }
    }//內部類 止

    void test() {
        InnerOne inner = new InnerOne();// 可以訪問
        inner.display();
        inner.display2();
        // System.out.println("Inner y:" + inner_y); // 不能訪問內部內變量
        System.out.println("Inner y:" + inner.innerone_public_name);// 可以訪問
        System.out.println("Inner z:" + inner.innerone_private_name);// 可以訪問

        InnerTwo innerTwo = new InnerTwo();
        innerTwo.show();
    }
}

public class test {
    public static void main(String args[]) {
        Outer outer = new Outer();
        // Outer.InnerOne a=outer.getInnerOne();
        // InnerOne類是私有的,外部類不能訪問, 如果InnerOne類是public ,則可以.
        outer.test();
    }
}

內部類InnerOne及InnterTwo只在類Outer的作用域內是可知的, 如果類Outer外的任何代碼嘗試初始化類Inner或使用它, 編譯就不會通過.同時, 內部類的變量成員只在內部內內部可見, 若外部類或同層次的內部類需要訪問, 需採用示例程序
中的方法, 不可直接訪問內部類的變量.

(二)方法中定義的內部類

package com.guxilong;


public class test {
    int out_x = 100;

    public void test() {//方法內部的內部類
        class Inner {
            String inner_x = "x";

            void display() {
                System.out.println(out_x);
            }
        }
        Inner inner = new Inner();
        inner.display();
    }

    public void showStr(String str) {
        // public String str1 = "test Inner";
        // 不可定義, 只允許final修飾
        // static String str4 = "static Str";
        // 不可定義, 只允許final修飾
        String str2 = "test Inner";
        final String str3 = "final Str";
        class InnerTwo {
            public void testPrint() {
                System.out.println(out_x);
                // 可直接訪問外部類的變量
                // System.out.println(str2); // 不可訪問本方法內部的非final變量
                System.out.println(str3); // 只可訪問本方法的final型變量成員
            }
        }
        InnerTwo innerTwo = new InnerTwo();
        innerTwo.testPrint();
    }

    public void use() {
        // Inner innerObj = new Inner();//此時Inner己不可見了
        // System.out.println(Inner.x);//此時Inner己不可見了
    }

    public static void main(String[] args) {
        test outer = new test();
        outer.test();
    }
}

從上面的例程我們可以看出定義在方法內部的內部類的可見性更小, 它只在方法內部
可見, 在外部類(及外部類的其它方法中)中都不可見了.同時, 它有一個特點, 就是方法內的內部類連本方法的成員變量都不可訪問, 它只能訪問本方法的final型成員.同時另一個需引起注意的是方法內部定義成員, 只允許final修飾或不加修飾符, 其它像static等均不可用. 

(三)匿名內部類

本質:是一個繼承了該類或者實現了該接口的子類匿名對象

 new Inter() {

      Public void print(){

      Sysotem.out.println.(print);

      }

    }.print();

PS:匿名內部類只針對重寫一個方法時使用

多個方法的話可以用多態來解決。

內部類調用外部定義的對象,那麼其參數引用是final類型的

參考:https://blog.csdn.net/machinecat0898/article/details/80071242

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