1. 程式人生 > >Java複習之內部類

Java複習之內部類

1.內部類的基本概念

內部類就是在一個類的內部定義的類

成員內部類定義如下:

class Outer{
    class Inner{}
}

編譯以後會產生兩個檔案

Outer.class Outer$Inner.class

2.在外部建立內部類的物件

內部類除了可以在外部類中產生例項化物件,也可以在外部類的外部來例項化。那麼,根據內部類生成的*.class檔案:Outer$Inner.class , “$”符號在程式的執行時將被替換成“.”所以內部類的訪問:通過“外部類.內部類”的形式表示。

//產生外部類的例項
Outer out = new Outer();
//宣告內部類物件
Outer.Inner in = null; //例項化內部類物件 in = out.new Inner();

成員內部類的Demo:

public class InnerClassDemo1 {
    public static void main(String args[])
    {
        Dog d = new Dog("花花");
        d.say();
        //宣告內部類的引用
        Dog.ChildDog child = null;
        //建立內部類的例項,但是該方法一般不使用
        child = d.new
ChildDog(); child.talk(); //比較常用的方法 d.childTalk(); } } //狗類 class Dog{ private String name; public Dog(String name) { this.name=name; } public void say() { System.out.println("我是一隻狗,主人叫我"+name); } //內部類(成員內部類) class ChildDog{ public
void talk(){ //內部類可以直接使用外部類的屬性 System.out.println("我是一隻狗,我媽是"+name); } } //直接在外部類的內部定義方法 public void childTalk() { ChildDog child = new ChildDog(); child.talk(); } }

3.方法內部類

內部類可以作為一個類的成員外,還可以把類放在方法內定義

格式:

class Outer
{
public void doSomething()
{
    class Inner{
        public void seeOuter(){}
    }
}
}

注意
(1)方法內部類只能在定義該內部類的方法內例項化,不可以在此方法外對其例項化
(2)方法內部類物件不能使用該內部類所在方法的非final區域性變數

public class InnerClassDemo2 {
    public static void main(String args[])
    {
        Dog1 d = new Dog1("花花");
        d.childTalk();
    }
}
class Dog1{
    private String name;
    public Dog1(String name)
    {
        this.name=name;
    }
    public void say()
    {
        System.out.println("我是一隻狗,主人叫我"+name);
    }
    //在方法裡面宣告一個內部類
    public void childTalk()
    {
        class ChildDog1{
            public void talk()
            {
                System.out.println("我是一隻狗狗,我媽媽是"+name);
            }
        }
        //只能在這裡進行例項化,因為涉及到作用域
        ChildDog1 childDog1 = new ChildDog1();
        childDog1.talk();
    }
}

4.靜態內部類
在一個類內部定義一個靜態內部類,靜態的含義是該內部類可以像其他靜態成員一樣,沒有外部類物件時,也能夠訪問它。靜態巢狀類僅能訪問外部類的靜態成員和方法。

public class InnerClassDemo3 {
    public static void main(String args[])
    {
        //注意靜態內部類與成員內部類在宣告例項化物件時的區別
        Dog.ChildDog child = new Dog.ChildDog();
        child.talk();

        Dog.childTalk();
    }
}

class Dog{
    static private String name;
    public Dog(String name)
    {
        this.name=name;
    }
    public void say()
    {
        System.out.println("我是一隻狗,主人叫我"+name);
    }

    //靜態內部類
    static class ChildDog{
        public void talk()
        {
            //靜態內部類只能訪問外部類中的靜態成員和方法
            System.out.println("我是一隻狗狗");
        }
    }
    public static void childTalk()
    {
        ChildDog c = new ChildDog();
        c.talk();
    }
}

5.匿名內部類

沒有名字的內部類

匿名內部類的三種情況

(1)繼承式的匿名內部類
(2)介面式的匿名內部類
(3)引數式的匿名內部類

public class InnerClassDemo4 {
    public static void main(String args[])
    {
        //1.繼承式匿名內部類,{}表示實現1個子類
            Dog1 dog1 = new Dog1("小白"){
            public void say()
            {
                System.out.println("我是一隻母狗,主人叫我"+name);
            }
        };
        dog1.say();
        //2.介面式的匿名內部類,{}中是介面的實現
        Child child = new Child() {
            @Override
            public void talk() {
            System.out.println("我是一隻小狗狗");
            }
        };
        child.talk();
        //3.引數式的匿名內部類
        childTalk(new Child() {
            @Override
            public void talk() {
                System.out.println("我是一隻小狗狗");
            }
        });
    }
    public static void childTalk(Child c){
        c.talk();
    }
}
class Dog1
{
    protected String name;
    public Dog1(String name){
        this.name=name;
    }
    public void say()
    {
        System.out.println("我是一隻狗,主人叫我"+name);
    }
}

interface Child{
    public void talk();
}

匿名內部類省去了去單獨實現一個介面或者繼承一個來創造例項的麻煩,直接在例項化的同時實現相應的內部類。

6內部類的作用

每個內部類都能獨立地繼承自一個(介面的)實現,所以無論外部類是否已經繼承了某個介面的實現,對於內部類都沒有影響。如果沒有內部類提供的可以繼承多個具體的或者抽象的類的能力,一些設計與程式設計問題就很難解決。從這個角度看,內部類使得多重繼承的解決方案變得更完整。介面解決了部分問題,而內部類有效地的實現了“多重繼承”