1. 程式人生 > >2018.10.12學習筆記

2018.10.12學習筆記

10.12學習筆記

今天學習了《Java程式設計思想》的第十章—內部類的後半部分。下面對今日收穫與疑惑作一個總結。


1.匿名內部類:
返回值的生成與表示這個返回值的類的定義結合在一起。另外,這個類是匿名的,他沒有名字。
①由於匿名內部類沒有名字,所以使用構造程式碼塊來代替建構函式

public abstract class Base {
    public Base(int i){
        System.out.println("Base constructor, i = " + i);
    }

    public abstract void test();
}


public class AnonymousBase {
    public Base getBase(int i){
        return new Base(5){
            {System.out.println("AnonymousBase initializer");}//構造程式碼塊充當了建構函式的功能
            @Override
            public void test() {
                System.out.println("fuQian");
            }
        };
    }

    public static void main(String args[]){
        AnonymousBase anonymousBase = new AnonymousBase();
        anonymousBase.getBase(5).test();
    }
}

但是它收到了限制,不能過載例項初始化方法

2.構造程式碼塊:
構造程式碼塊在類中用{}定義,作用是給物件進行初始化。構造程式碼塊與建構函式的區別是:構造程式碼塊是給所有的物件進行統一初始化,而建構函式是給對應的物件進行初始化

①靜態程式碼塊與非靜態程式碼塊:
非靜態程式碼塊無論建立哪個物件,都會先執行相同的程式碼塊—構造程式碼塊中定義的是不同物件共性的初始化內容。靜態程式碼塊,它是隨著類的載入而執行,只執行一次。但無論是靜態程式碼塊還是非靜態程式碼塊,都會在構造方法呼叫之前被載入

②初始化順序:
先載入靜態的,即靜態構造塊(類靜態屬性),然後才是非靜態的構造塊(非靜態屬性),最後才是呼叫類構造方法。注意靜態的,即靜態構造塊和靜態屬性不分先後,按在類定義的先後順序進行初始化

3.巢狀類(靜態內部類):
介面中的內部類:
巢狀類可以作為介面的一部分,因為類是static的,所以不違反介面的規則。放在介面中的任何類都自動地是public和static的,你甚至可以在內部類中實現其外圍介面

public interface ClassInInterface {
    void howdy();

    class Test implements ClassInInterface{
        @Override
        public void howdy(){
            System.out.println("介面的巢狀類");
        }
        static class Tester{
            public static void main(String args[]){
                Test test = new Test();
                test.howdy();
            }
        }
    }
}

4.為什麼需要內部類:
每個內部類都能獨立地實現一個介面或者繼承具體、抽象的類(相當於實現了多重繼承),或者可以讓多個類以不同的方式實現同一個介面或繼承自同一個類

public interface Selector {
    boolean end();
    Object current();
    void next();
}


/*
description:在同一個類中,建立兩個內部類實現了Selector介面的不同實現,從而實現了向前和向後進行遍歷
 */
public class Sequence {
    private Object[] items;
    private int next = 0;

    public Sequence(int size){
        items = new Object[size];
    }

    public void add(Object x){
        if (next < items.length){
            items[next++] = x;
        }
    }

    private class SequenceSelector implements Selector{
        private int i;

        @Override
        public boolean end(){
            return i == items.length;
        }

        @Override
        public Object current(){
            return items[i];
        }

        @Override
        public void next(){
            if (i<items.length)
                i++;
        }
    }

    private class SequenceSelector_reverse implements Selector{
        private int i = items.length -1;

        @Override
        public boolean end(){
            return i == -1;
        }

        @Override
        public Object current(){
            return items[i];
        }

        @Override
        public void next(){
            if (i>=0)
                i--;
        }
    }

    public Selector selector(){
        return new SequenceSelector();
    }

    public Selector selector_reverse(){
        return new SequenceSelector_reverse();
    }

    public static class Tester{
        public static void main(String args[]){
            Sequence sequence = new Sequence(10);
            Sequence sequence_reverse = new Sequence(10);
            for (int i = 0;i< sequence.items.length;i++){
                sequence.add(i);
                sequence_reverse.add(i);
            }
            Selector selector = sequence.new SequenceSelector();
            Selector selector_reverse = sequence.new SequenceSelector_reverse();

            while (!selector.end()){
                System.out.print(selector.current() + " ");
                selector.next();
            }

            while(!selector_reverse.end()){
                System.out.print(selector_reverse.current() + " ");
                selector_reverse.next();
            }
        }
    }
}/*output
0 1 2 3 4 5 6 7 8 9 9 8 7 6 5 4 3 2 1 0
*/

5.內部類的繼承:
因為內部類的構造器必須連線到指向其外部類物件的引用,所以,那個指向外部類物件的引用必須被初始化

public class FirstOuter {
    class FirstInner{
        public FirstInner(int i){
            System.out.println("第一個內部類" + i);
        }
    }
}


public class SecondOuter {
    class SecondInner extends FirstOuter.FirstInner{
        SecondInner(FirstOuter firstOuter,int i){ //外部類物件的引用以及傳入的引數
            firstOuter.super(i);
        }
    }
}