Java基礎(chǔ)之內(nèi)部類

該項(xiàng)目源碼地址:https://github.com/ggb2312/JavaNotes/tree/master/java-basic

1. 簡介

可以將一個(gè)類的定義放在另一個(gè)類的定義內(nèi)部,這就是內(nèi)部類。

一般格式為:

public class Zoo{
    ...
    class Panda{
    }
}

內(nèi)部類是一種非常有用的特性,它允許你把一些邏輯相關(guān)的類組織在一起,并控制位于內(nèi)部的類的可見性。內(nèi)部類與組合是完全不同的概念。

內(nèi)部類提供一種代碼隱藏機(jī)制:“將類置于其他類的內(nèi)部”,同時(shí)內(nèi)部類也了解外部類,并能與之通信。

2. 內(nèi)部類實(shí)例

內(nèi)部類有以下四種形式

  1. 成員內(nèi)部類
  2. 局部內(nèi)部類
  3. 靜態(tài)內(nèi)部類
  4. 匿名內(nèi)部類

成員內(nèi)部類和靜態(tài)內(nèi)部類可以擁有private訪問權(quán)限、protected訪問權(quán)限、public訪問權(quán)限及包訪問權(quán)限。比如上面的例子,如果成員內(nèi)部類Inner用private修飾,則只能在外部類的內(nèi)部訪問,如果用public修飾,則任何地方都能訪問;如果用protected修飾,則只能在同一個(gè)包下或者繼承外部類的情況下訪問;如果是默認(rèn)訪問權(quán)限,則只能在同一個(gè)包下訪問。這一點(diǎn)和外部類有一點(diǎn)不一樣,外部類只能被public和包訪問兩種權(quán)限修飾。我個(gè)人是這么理解的,由于成員內(nèi)部類看起來像是外部類的一個(gè)成員,所以可以像類的成員一樣擁有多種權(quán)限修飾。

下面我們通過幾個(gè)實(shí)例來看看內(nèi)部類具體長什么樣。

2.1 成員內(nèi)部類

成員內(nèi)部類和成員變量一樣,屬于類的全局成員。
成員內(nèi)部類可以擁有private訪問權(quán)限、protected訪問權(quán)限、public訪問權(quán)限及包訪問權(quán)限。

一般格式:

public class OuterClass { //外部類
     int id; // 成員變量
     class InnerClass { //成員內(nèi)部類
     }
}

實(shí)例:

一個(gè)類作為另一個(gè)類的成員(不是作為成員變量,作為成員變量的話就成組合模式了),同時(shí)成員內(nèi)部類可以無條件的使用外部類的一切靜態(tài)變量、成員變量、靜態(tài)方法、成員方法,用于內(nèi)部類和外部類通信。

public class OuterClass {
    private String name;

    public OuterClass(String name) {
        this.name = name;
    }

    // 成員內(nèi)部類,類比對(duì)象的成員變量
    private class InnerClass {
        int innerPrice;

        public InnerClass(int innerPrice) {
            System.out.println("成員內(nèi)部類~類比對(duì)象的成員變量");
            this.innerPrice = innerPrice;
        }

        public void print() {
            helloInnerClass();
            System.out.println("出售:" + name + " 單價(jià):" + innerPrice);
        }
    }

    public void helloInnerClass() {
        System.out.println("我是外部類的helloInnerClass方法,內(nèi)部類你可以調(diào)用我");
    }

    public static void main(String[] args) {
        OuterClass sample = new OuterClass("香蕉");
        InnerClass inner = sample.new InnerClass(20);
        inner.print();
    }
}

運(yùn)行結(jié)果:

成員內(nèi)部類~類比對(duì)象的成員變量
我是外部類,內(nèi)部類你可以調(diào)用我
出售:香蕉 單價(jià):20

2.2 局部內(nèi)部類

局部內(nèi)部類和局部變量一樣,都是在方法內(nèi)定義的,其有效范圍只在方法內(nèi)有效。

一般格式:

public class OuterClass { //外部類
    public void print(){ // print方法
         class InnerClass { //局部內(nèi)部類
         }
    }
}

實(shí)例:

局部內(nèi)部類可以無條件的使用外部類的一切靜態(tài)變量、成員變量、靜態(tài)方法、成員方法,用于內(nèi)部類和外部類通信。

public class OuterClass {

    private String name;

    public OuterClass(String name) {
        this.name = name;
    }

    public void helloInnerClass() {
        System.out.println("我是外部類的helloInnerClass方法,內(nèi)部類你可以調(diào)用我");
    }

    public void print(int price) {
        // 局部內(nèi)部類,類比方法內(nèi)的局部變量
        class InnerClass {
            int innerPrice;

            public InnerClass(int innerPrice) {
                System.out.println("局部內(nèi)部類~類比方法內(nèi)的局部變量");
                this.innerPrice = innerPrice;
            }

            public void sell() {
                helloInnerClass();
                System.out.println("出售:" + name + " 單價(jià):" + innerPrice);
            }
        }
        InnerClass apple = new InnerClass(price);
        apple.sell();
    }

    public static void main(String[] args) {
        OuterClass outerClass = new OuterClass("蘋果");
        outerClass.print(10);
    }
}

運(yùn)行結(jié)果:

局部內(nèi)部類~類比方法內(nèi)的局部變量
我是外部類的helloInnerClass方法,內(nèi)部類你可以調(diào)用我
出售:蘋果 單價(jià):10

2.3 靜態(tài)內(nèi)部類

靜態(tài)內(nèi)部類和靜態(tài)變量類似,它都是使用static關(guān)鍵字修飾。
靜態(tài)內(nèi)部類可以擁有private訪問權(quán)限、protected訪問權(quán)限、public訪問權(quán)限及包訪問權(quán)限。

一般格式:

public class OuterClass { //外部類
   class InnerClass { //靜態(tài)內(nèi)部類
   }     
}

實(shí)例:

靜態(tài)內(nèi)部類只能使用外部類的一切成員變量、成員方法,用于內(nèi)部類和外部類通信。

public class OuterClass {
    private static String name="靜態(tài)內(nèi)部類";

    // 靜態(tài)內(nèi)部類,類比類的靜態(tài)變量
    private static class InnerClass {
        public void print() {
            System.out.println(name+"~類比類的的靜態(tài)變量");
        }
    }

    public static void main(String[] args) {
        OuterClass.InnerClass sample = new OuterClass.InnerClass();
        sample.print();
    }
}

運(yùn)行結(jié)果:

靜態(tài)內(nèi)部類~類比類的的靜態(tài)變量

2.4 匿名內(nèi)部類

匿名內(nèi)部類就是沒有名字的內(nèi)部類,其名稱由Java編譯器給出,一般是形如:“外部類名稱+$+匿名類順序”,沒有名稱也就是其他地方就不能引用。其必須要實(shí)現(xiàn)一個(gè)接口或者繼承一個(gè)父類,主要是用來簡化代碼,常常用于Swing程序設(shè)計(jì)中的事件監(jiān)聽處理。

一般格式:

public class OuterClass { //外部類
   public void print(){ // print方法
         new InnerClass(){
           ...  
         };
    }     
}

實(shí)例:

匿名內(nèi)部類只能使用外部類的一切成員變量、成員方法,用于內(nèi)部類和外部類通信。

定義一個(gè)接口

public interface InnerClass {
    // 接口方法默認(rèn)public
    void print();
}

定義一個(gè)外部類

public class OuterClass {

    public static void print(InnerClass innerClass) {
        innerClass.print();
    }

    public static void main(String[] args) {
        OuterClass.print(new InnerClass() {
            @Override
            public void print() {
                System.out.println("匿名內(nèi)部類~由于沒有引用,每次新創(chuàng)建的,在Minor GC時(shí)被清除");
            }
        });
    }
}

運(yùn)行結(jié)果:

匿名內(nèi)部類~由于沒有引用,每次新創(chuàng)建的,在Minor GC時(shí)被清除

匿名內(nèi)部類的名稱:外部類名稱+$+匿名類順序

匿名內(nèi)部類的名稱

使用JDK8提供的lambda表示替換匿名內(nèi)部類

public class OuterClass {

    public static void print(InnerClass innerClass) {
        innerClass.print();
    }

    public static void main(String[] args) {
        OuterClass.print(() -> System.out.println("匿名內(nèi)部類~由于沒有引用,每次新創(chuàng)建的,在Minor GC時(shí)被清除"));
    }
}

匿名內(nèi)部類在Swing中的實(shí)例:

import javax.swing.*;
import java.awt.*;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class test extends JFrame{
    JPasswordField passwordField;
    JTextField textField;
        test(){
            super();
            setTitle("QQ");
            setBounds(100, 100, 380, 280); 
            getContentPane().setLayout(null); 
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
             
            textField = new JTextField("密碼");
            textField.setBounds(100, 155, 120, 21);
            getContentPane().add(textField);
            // new MouseAdapter()使用匿名內(nèi)部類
            textField.addMouseListener(new MouseAdapter(){
                @Override
                public void mouseClicked(MouseEvent e) {
                    getContentPane().remove(textField);
                    passwordField = new JPasswordField();
                    passwordField.setBounds(100, 155, 120, 21); 
                    getContentPane().add(passwordField);
                }
            });
             
        }
        public static void main(String[] args) {
            new test().setVisible(true);;
        }
}

在給textField添加鼠標(biāo)監(jiān)聽事件的時(shí)候,使用了new MouseAdapter(){}匿名內(nèi)部類作為方法的參數(shù)。

3. 深入理解內(nèi)部類

1. 為什么成員內(nèi)部類可以無條件訪問外部類的成員和類屬性?
成員內(nèi)部類可以無條件訪問外部類的成員變量、static變量、成員函數(shù)和static函數(shù)。

public class Outter {
    private static int b = 2;
    private int a = 1;

    protected class Inner {
        public Inner() {
            System.out.println(a);//成員變量
            System.out.println(b);//static變量
            print();//成員函數(shù)
            staticPrint();//static函數(shù)
        }
    }
    private void print() {
    }

    private static void staticPrint() {
    }
}

我們通過反編譯字節(jié)碼文件看看究竟是如何實(shí)現(xiàn)的。在編譯時(shí),會(huì)將內(nèi)部類單獨(dú)編譯成一個(gè)字節(jié)碼文件。

字節(jié)碼文件

Outter.class是外部類的字節(jié)碼文件,Outter$Inner.class才是成員內(nèi)部類的字節(jié)碼文件。

反編譯Outter$Inner.class文件

javap -v Outter$Inner.class

得到一個(gè)關(guān)鍵信息

final cn.lastwhisper.javabasic.InnerClass.member.Outter this$0;

這是一個(gè)指向外部類對(duì)象的指針。也就是說編譯器會(huì)默認(rèn)為成員內(nèi)部類添加了一個(gè)指向外部類對(duì)象的引用,那么這個(gè)引用是如何賦初值的呢?下面接著看內(nèi)部類的構(gòu)造器:

public cn.lastwhisper.javabasic.InnerClass.member.Outter$Inner(cn.lastwhisper.javabasic.InnerClass.member.Outter);

從這里可以看出,雖然我們?cè)诙x的內(nèi)部類的構(gòu)造器是無參構(gòu)造器,編譯器還是會(huì)默認(rèn)添加一個(gè)參數(shù),該參數(shù)的類型為指向外部類對(duì)象的一個(gè)引用,所以成員內(nèi)部類中的Outter this&0 指針便指向了外部類對(duì)象,因此可以在成員內(nèi)部類中隨意訪問外部類的成員。從這里也間接說明了成員內(nèi)部類是依賴于外部類的,如果沒有創(chuàng)建外部類的對(duì)象,則無法對(duì)Outter this&0引用進(jìn)行初始化賦值,也就無法創(chuàng)建成員內(nèi)部類的對(duì)象了。

2. 為什么靜態(tài)內(nèi)部類只能訪問外部類的成員屬性?
靜態(tài)內(nèi)部類只能訪問外部類的static變量和static函數(shù)。

public class Outter {
    private static int b = 2;
    private int a = 1;

    protected static class Inner {
        public Inner() {
            //System.out.println(a);//成員變量 會(huì)報(bào)錯(cuò)“Non-static field 'a' cannot be referenced from a static context”
            System.out.println(b);//static變量
            //print();//成員函數(shù) 會(huì)報(bào)錯(cuò)“Non-static field 'a' cannot be referenced from a static context”
            staticPrint();//static函數(shù)
        }
    }

    private void print() {
    }

    private static void staticPrint() {
    }
}

如果靜態(tài)內(nèi)部類使用外部類的成員變量,就會(huì)報(bào)錯(cuò)“Non-static field 'a' cannot be referenced from a static context”,從字面意思很好理解,非static字段不能被static上下文所引用。靜態(tài)內(nèi)部類使用外部類的成員函數(shù)情況也類似。

類比著上一個(gè)問題,通過反編譯字節(jié)碼文件,發(fā)現(xiàn)編譯器在編譯時(shí)并沒有添加外部類的引用,所以靜態(tài)內(nèi)部類也無法使用外部類的成員變量和成員函數(shù)。

public cn.lastwhisper.javabasic.InnerClass.Static.Outter$Inner();

3. 為什么匿名內(nèi)部類只能訪問final修飾的局部變量?

在JDK8以前匿名內(nèi)部類只能訪問final修飾的局部變量,在JDK8以后匿名內(nèi)部類可以訪問非final修飾的局部變量

想必這個(gè)問題也曾經(jīng)困擾過很多人,在討論這個(gè)問題之前,先看下面這段代碼:

public class FinalTest {
    public void test(final int b) {
        final int a = 100;
        new Thread() {
            public void run() {
                System.out.println(a);
                System.out.println(b);
            }
        }.start();
    }
}

這段代碼會(huì)被編譯成兩個(gè)class文件:FinalTest$1.class和FinalTest.class

匿名內(nèi)部類字節(jié)碼文件

默認(rèn)情況下,編譯器會(huì)為匿名內(nèi)部類起名為“外部類名稱+$+匿名類順序”

即test方法里面的匿名內(nèi)部類為:FinalTest$1.class

上段代碼中,如果把變量a和b前面的任一個(gè)final去掉,這段代碼都編譯不過。我們先考慮這樣一個(gè)問題:

當(dāng)test方法執(zhí)行完畢之后,局部變量a的生命周期就結(jié)束了,而此時(shí)Thread對(duì)象的生命周期很可能還沒有結(jié)束,那么在Thread的run方法中繼續(xù)訪問test方法的局部變量a就變成不可能了,但是又要實(shí)現(xiàn)這樣的效果,怎么辦呢?Java采用了 復(fù)制 的手段來解決這個(gè)問題。將這段代碼的字節(jié)碼反編譯可以得到下面的內(nèi)容:

反編譯FinalTest$1.class

得到的信息很多,我們分成兩個(gè)部分。
第一部分run方法

run方法

我們看到在run方法中有一條指令:

bipush 100

這條指令表示將操作數(shù)100壓棧,表示使用的是一個(gè)本地局部變量。這個(gè)過程是在編譯期間由編譯器默認(rèn)進(jìn)行,如果這個(gè)變量的值在編譯期間可以確定,則編譯器默認(rèn)會(huì)在匿名內(nèi)部類的常量池中添加一個(gè)內(nèi)容相等的字面量或者直接將相應(yīng)的字節(jié)碼嵌入到執(zhí)行字節(jié)碼中。

這樣一來,匿名內(nèi)部類方法中引用的變量其實(shí)并不是外部類方法中的局部變量,而是引用編譯器在匿名內(nèi)部類的常量池中添加的一個(gè)內(nèi)容相等的字面量。即匿名內(nèi)部類run方法中使用的a并不是test方法中的a,而是FinalTest$1常量池中的a=100。

第二部分匿名內(nèi)部類的構(gòu)造函數(shù)

匿名內(nèi)部類的構(gòu)造函數(shù)

我們看到匿名內(nèi)部類FinalTest$1的構(gòu)造器含有兩個(gè)參數(shù),一個(gè)是指向外部類對(duì)象的引用,一個(gè)是int型變量,很顯然,這里是將變量test方法中的形參b以參數(shù)的形式傳進(jìn)來對(duì)匿名內(nèi)部類中的拷貝(變量b的復(fù)制)進(jìn)行賦值初始化。

也就說如果局部變量的值在編譯期間就可以確定,則直接在匿名內(nèi)部里面創(chuàng)建一個(gè)拷貝。如果局部變量的值無法在編譯期間確定,則通過構(gòu)造器傳參的方式來對(duì)拷貝進(jìn)行初始化賦值。

這樣一來就解決了前面所說的生命周期不一致的問題。但是新的問題又來了,既然在run方法中訪問的變量a和test方法中的變量a不是同一個(gè)變量,當(dāng)在run方法中改變變量a的值的話,會(huì)出現(xiàn)什么情況?

對(duì),會(huì)造成數(shù)據(jù)不一致性,這樣就達(dá)不到原本的意圖和要求。為了解決這個(gè)問題,java編譯器就限定必須將變量a限制為final變量,不允許對(duì)變量a進(jìn)行更改(對(duì)于引用類型的變量,是不允許指向新的對(duì)象),這樣數(shù)據(jù)不一致性的問題就得以解決了。

至此我們可以回答“為什么匿名內(nèi)部類只能訪問final修飾的局部變量?”了。

1. Java為了避免數(shù)據(jù)不一致性的問題,做出了匿名內(nèi)部類只可以訪問final的局部變量的限制。

2. 補(bǔ)充:Java為了局部變量與匿名內(nèi)部類生命周期不一致的問題,將匿名內(nèi)部類使用到的外部類方法局部變量復(fù)制到自己的常量池中一份,操作時(shí)只使用自己常量池中的數(shù)據(jù)。

4. 為什么需要內(nèi)部類

至此我們已經(jīng)看到了許多描述內(nèi)部類的語法和語義,但是這并不能回答“為什么需要內(nèi)部類” 這個(gè)問題。

一般說來,內(nèi)部類繼承自某個(gè)類或?qū)崿F(xiàn)某個(gè)接口,內(nèi)部類的代碼操作創(chuàng)建它的外圍類的對(duì)象。所以可以認(rèn)為內(nèi)部類提供了某種進(jìn)入其外圍類的窗口。

內(nèi)部類必須要回答的一個(gè)問題是:如果只是需要一個(gè)對(duì)接口的引用,為什么不通過外圍類實(shí)現(xiàn)那個(gè)接口呢?答案是:“如果這能滿足需求,那么就應(yīng)該這樣做?!?那么內(nèi)部類實(shí)現(xiàn)一個(gè)接口與外圍類實(shí)現(xiàn)這個(gè)接口有什么區(qū)別呢?答案是:后者不是總能享用到接口帶來的方便, 有時(shí)需要用到接口的實(shí)現(xiàn)。所以,使用內(nèi)部類最吸引人的原因是 :

每個(gè)內(nèi)部類都能獨(dú)立地繼承自一個(gè)(接口的)實(shí)現(xiàn),所以無論外圍類是否已經(jīng)繼承了某個(gè)(接口的)實(shí)現(xiàn),對(duì)于內(nèi)部類都沒有影響。

內(nèi)部類使得多重繼承的解決方案變得完整。接口解決了部分問題,而內(nèi)部類有效地實(shí)現(xiàn)了 “多重繼承” 。 也就是說,內(nèi)部類允許繼承多個(gè)非接口類型(類或抽象類)。

實(shí)例:

使用一個(gè)類繼承兩個(gè)抽象類,模擬“多繼承問題”

abstract class MyClass1 { }
abstract class MyClass2 { }

/**
 * 成員內(nèi)部類實(shí)例
 * @author lastwhisper
 */
public class OuterClass extends MyClass1 {
    private String name;

    public OuterClass(String name) {
        this.name = name;
    }

    // 成員內(nèi)部類,類比對(duì)象的成員變量
    class InnerClass extends MyClass2 {
        int innerPrice;

        public InnerClass(int innerPrice) {
            System.out.println("成員內(nèi)部類~類比對(duì)象的成員變量");
            this.innerPrice = innerPrice;
        }

        public void print() {
            helloInnerClass();
            System.out.println("出售:" + name + " 單價(jià):" + innerPrice);
        }
    }

    public void helloInnerClass() {
        System.out.println("我是外部類的helloInnerClass方法,內(nèi)部類你可以調(diào)用我");
    }

    public static void main(String[] args) {
        OuterClass sample = new OuterClass("香蕉");
        InnerClass inner = sample.new InnerClass(20);
        inner.print();
    }
}

如果不需要解決“多重繼承” 的問題,那么自然可以用別的方式編碼,而不需要使用內(nèi)部類。但如果使用內(nèi)部類,還可以獲得其他一些特性:

  1. 內(nèi)部類可以有多個(gè)實(shí)例,每個(gè)實(shí)例都有自己的狀態(tài)信息,并且與其外圍類對(duì)象的信息相互獨(dú)立。
  2. 在單個(gè)外圍類中,可以讓多個(gè)內(nèi)部類以不同的方式實(shí)現(xiàn)同一個(gè)接口,或繼承同一個(gè)類。
  3. 創(chuàng)建內(nèi)部類對(duì)象的時(shí)刻并不依賴于外圍類對(duì)象的創(chuàng)建。
  4. 內(nèi)部類并沒有令人迷惑的“is-a”關(guān)系; 它就是一個(gè)獨(dú)立的實(shí)體 。

5. 總結(jié)

訪問權(quán)限:

  1. 成員內(nèi)部類和靜態(tài)內(nèi)部類可以擁有private訪問權(quán)限、protected訪問權(quán)限、public訪問權(quán)限及包訪問權(quán)限。
  2. 如果成員內(nèi)部類Inner用private修飾,則只能在外部類的內(nèi)部訪問,如果用public修飾,則任何地方都能訪問;如果用protected修飾,則只能在同一個(gè)包下或者繼承外部類的情況下訪問;如果是默認(rèn)訪問權(quán)限,則只能在同一個(gè)包下訪問。
  3. 這一點(diǎn)和外部類有一點(diǎn)不一樣,外部類只能被public和包訪問兩種權(quán)限修飾。我個(gè)人是這么理解的,由于成員內(nèi)部類看起來像是外部類的一個(gè)成員,所以可以像類的成員一樣擁有多種權(quán)限修飾。

資源使用:

  1. 成員內(nèi)部類可以無條件的使用外部類的一切靜態(tài)變量、成員變量、靜態(tài)方法、成員方法,用于內(nèi)部類和外部類通信。
  2. 局部內(nèi)部類可以無條件的使用外部類的一切靜態(tài)變量、成員變量、靜態(tài)方法、成員方法,用于內(nèi)部類和外部類通信。
  3. 靜態(tài)內(nèi)部類只能使用外部類的一切成員變量、成員方法,用于內(nèi)部類和外部類通信。
  4. 匿名內(nèi)部類只能使用外部類的一切成員變量、成員方法,用于內(nèi)部類和外部類通信。

使用內(nèi)部類的好處:

  1. 可以解決“多繼承問題”
  2. 內(nèi)部類可以有多個(gè)實(shí)例,每個(gè)實(shí)例都有自己的狀態(tài)信息,并且與其外圍類對(duì)象的信息相互獨(dú)立。
  3. 在單個(gè)外圍類中,可以讓多個(gè)內(nèi)部類以不同的方式實(shí)現(xiàn)同一個(gè)接口,或繼承同一個(gè)類。
  4. 創(chuàng)建內(nèi)部類對(duì)象的時(shí)刻并不依賴于外圍類對(duì)象的創(chuàng)建。
  5. 內(nèi)部類并沒有令人迷惑的“is-a”關(guān)系; 它就是一個(gè)獨(dú)立的實(shí)體 。

參考

《Java編程思想》
https://www.cnblogs.com/dolphin0520/p/3811445.html
https://www.cnblogs.com/cuipengfei/p/3150542.html#3901831

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一、內(nèi)部類介紹 內(nèi)部類:將一個(gè)類的定義放在另一個(gè)類的定義內(nèi)部。 內(nèi)部類是個(gè)編譯時(shí)的概念,一旦編譯成功后,它就與外圍...
    代碼米蟲閱讀 881評(píng)論 0 0
  • 1、內(nèi)部類分類: 成員內(nèi)部類 局部內(nèi)部類 匿名內(nèi)部類 靜態(tài)內(nèi)部類 2、成員內(nèi)部類 1.概念: 定義在一個(gè)類內(nèi)部的類...
    M_JCs閱讀 938評(píng)論 0 9
  • 什么是內(nèi)部類?為什么要使用內(nèi)部類? ?內(nèi)部類是指在類的內(nèi)部可以定義另一個(gè)類。內(nèi)部類可以申明成public或priv...
    小任務(wù)大夢(mèng)想閱讀 373評(píng)論 0 0
  • 內(nèi)部類:類里面再聲明類 1》默認(rèn)內(nèi)部類 class Outer{ private int a = 12; clas...
    沈默的頭號(hào)狗腿閱讀 122評(píng)論 0 0
  • 今年的4月5日,清明節(jié),我和L走到了一起。 她算我的第二個(gè)女朋友。 今天我和她分開,整整六個(gè)月的時(shí)間。 決絕之后,...
    名再道號(hào)直行閱讀 463評(píng)論 0 1

友情鏈接更多精彩內(nèi)容