Java成員內部類和靜態內部類

Java成員內部類和靜態內部類java


使用內部類最吸引人的緣由是:每一個內部類都能獨立地繼承一個(接口的)實現,因此不管外圍類是否已經繼承了某個(接口的)實現,對於內部類都沒有影響。測試

在咱們程序設計中有時候會存在一些使用接口很難解決的問題,這個時候咱們能夠利用內部類提供的、能夠繼承多個具體的或者抽象的類的能力來解決這些程序設計問題。能夠這樣說,接口只是解決了部分問題,而內部類使得多重繼承的解決方案變得更加完整。this


其實使用內部類最大的優勢就在於它可以很是好的解決多重繼承的問題,可是若是咱們不須要解決多重繼承問題,那麼咱們天然可使用其餘的編碼方式,可是使用內部類還可以爲咱們帶來以下特性(摘自《Think in java》):編碼

一、內部類能夠用多個實例,每一個實例都有本身的狀態信息,而且與其餘外圍對象的信息相互獨立。spa

二、在單個外圍類中,可讓多個內部類以不一樣的方式實現同一個接口,或者繼承同一個類。.net

三、建立內部類對象的時刻並不依賴於外圍類對象的建立。設計

四、內部類並無使人迷惑的「is-a」關係,他就是一個獨立的實體。code

五、內部類提供了更好的封裝,除了該外圍類,其餘類都不能訪問。對象

在Java中內部類主要分爲成員內部類、局部內部類、匿名內部類、靜態內部類。blog

成員內部類:

成員內部類也是最普通的內部類,它是外圍類的一個成員,因此他是能夠無限制的訪問外圍類的全部成員屬性和方法,儘管是private的,可是外圍類要訪問內部類的成員屬性和方法則須要經過內部類實例來訪問。

在成員內部類中要注意兩點,第一:成員內部類中不能存在任何static的變量和方法;第二:成員內部類是依附於外圍類的,因此只有先建立了外圍類纔可以建立內部類。

靜態內部類:

關鍵字static中提到static能夠修飾成員變量、方法、代碼塊,其餘它還能夠修飾內部類,使用static修飾的內部類咱們稱之爲靜態內部類,不過咱們更喜歡稱之爲嵌套內部類。靜態內部類與非靜態內部類之間存在一個最大的區別,咱們知道非靜態內部類在編譯完成以後會隱含地保存着一個引用,該引用是指向建立它的外圍內,可是靜態內部類卻沒有。沒有這個引用就意味着:

一、 它的建立是不須要依賴於外圍類的。

二、 它不能使用任何外圍類的非static成員變量和方法。


代碼示例:

package binarytree;

/**
 * Created with IntelliJ IDEA.
 * User: ASUS
 * Date: 14-7-11
 * Time: 下午3:26
 * To change this template use File | Settings | File Templates.
 */
public class OuterClass {

    private int tmp;
    private int age;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getTmp() {
        return tmp;
    }

    public void setTmp(int tmp) {
        this.tmp = tmp;
    }

    /**
     * private 訪問權限
     * 成員內部類
     */
    private class InnerClass {
        private int a;
        private int b;

        public InnerClass(int a, int b) {
            this.a = a;
            this.b = b;
        }

        private int getA() {
            return a;
        }

        private void setA(int a) {
            this.a = a;
        }

        private int getB() {
            return b;
        }

        private void setB(int b) {
            this.b = b;
        }
    }


    public int doWithInnerClass() {
        InnerClass innerClass = new InnerClass(1, 2);
        if (innerClass.getA() > innerClass.getB()) {
            return innerClass.getA();
        } else {
            return innerClass.getB();
        }
    }


    /**
     * public 訪問權限
     * 成員內部類
     * <p/>
     * 成員內部類也是最普通的內部類,它是外圍類的一個成員,因此他是能夠無限制的訪問外圍類的
     * 全部成員屬性和方法,儘管是private的。可是外圍類要訪問內部類的成員屬性和方法則須要經過內部類實例來訪問。
     */
    public class PubInner {
        private int a;
        private int b;

        public PubInner(int a, int b) {
            this.a = a;
            this.b = b;
        }

        public int getA() {
            return a;
        }

        public void setA(int a) {
            this.a = a;
        }

        public int getB() {
            return b;
        }

        public void setB(int b) {
            this.b = b;
        }

        public int getTotal() {
            return tmp + a + b;
        }
    }


    /**
     * 默認訪問權限
     * 成員內部類
     */
    class DefaultInnerClass {
        private int a;
        private int b;

        public DefaultInnerClass(int a, int b) {
            this.a = a;
            this.b = b;
        }

        public int getA() {
            return a;
        }

        public void setA(int a) {
            this.a = a;
        }

        public int getB() {
            return b;
        }

        public void setB(int b) {
            this.b = b;
        }
    }

    /**
     * 靜態內部類
     * 訪問權限是static
     */
    public static class StaticInner {
        public static final int MAX = Integer.MAX_VALUE;

        private int a;
        private int b;

        public StaticInner(int a, int b) {
            this.a = a;
            this.b = b;
        }

        public int getA() {
            return a;
        }

        public void setA(int a) {
            this.a = a;
        }

        public int getB() {
            return b;
        }

        public void setB(int b) {
            this.b = b;
        }
    }
}

測試代碼:

package binarytree;

import org.junit.Test;

/**
 * Created with IntelliJ IDEA.
 * User: ASUS
 * Date: 14-7-11
 * Time: 下午3:05
 * To change this template use File | Settings | File Templates.
 */
public class TestInnverClass {


    /**
     * 對於內部類的訪問權限若是是private,則這個內部類是不可見的。
     */
    @Test
    public void test() {
        OuterClass outerClass = new OuterClass();
        int value = outerClass.doWithInnerClass();
        System.out.println(value);
    }


    /**
     * 測試public訪問權限的內部類
     */
    @Test
    public void test0877() {

        OuterClass.PubInner pubInner00 = new OuterClass().new PubInner(1, 2);
        System.out.println(pubInner00.getA());

        OuterClass outerClass = new OuterClass();
        outerClass.setTmp(233);
        OuterClass.PubInner pubInner = outerClass.new PubInner(1, 2);

        int a = pubInner.getA(), b = pubInner.getB();
        if (a > b) {
            System.out.println(a);
        } else {
            System.out.println(b);
        }

        System.out.println("Total=" + pubInner.getTotal());
    }


    /**
     * 測試靜態內部類,public訪問權限
     */
    @Test
    public void test2323() {
        OuterClass.StaticInner staticInner = new OuterClass.StaticInner(1, 2);
        int a = staticInner.getA(), b = staticInner.getB();
        if (a > b) {
            System.out.println(a);
        } else {
            System.out.println(b);
        }
    }


    /**
     * 默認訪問權限的內部類
     */
    @Test
    public void test9765() {
        OuterClass.DefaultInnerClass defaultInnerClass = new OuterClass().new DefaultInnerClass(1, 2);
        int a = defaultInnerClass.getA(), b = defaultInnerClass.getB();
        if (a > b) {
            System.out.println(a);
        } else {
            System.out.println(b);
        }
    }
}

關於public,private,protected,默認的訪問權限請看http://my.oschina.net/xinxingegeya/blog/212490

=====================END====================

相關文章
相關標籤/搜索