天天看點

靜态嵌套類(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