Java 剖析抽象類

 抽象類只是在普通類的基礎上擴充了一些抽象方法而已,所謂的抽象方法指的是隻聲明而未實現的方法(即沒有方法體)。

 所有抽象方法要求使用abstract關鍵字來定義,並且抽象方法所在的類也一定要使用abstract關鍵字來定義,表示抽象類。

 由於抽象方法沒有具體的方法實現,所以其抽象類是不能直接實例化的,使用抽象類的唯一途徑是使用它的實現子類。

 抽象類使用原則:

  • 所有抽象類必須有其實現子類。否則抽象類的存在毫無價值。
  • 抽象類的子類必須覆寫抽象類的所有抽象方法。但如果實現子類也是抽象類,那麼就不用了,但是最終,繼承關係中所有的抽象方法都要被實現類所覆寫。
  • 抽象類的對象雖然不能直接實例化,但是可以利用對象的多態性,實現子類向上轉型爲抽象父類實例化。
  • private不能修飾抽象類或抽象方法。這很好理解,private修飾對象或方法後,表示對外界和子類不可見,那麼對象和方法就不能被實現,那麼該對象和方法有什麼存在的價值呢。

 下面的例子是利用抽象類實現抽象類子類的封裝性。

abstract class Person {

    private String name;

    public abstract void printInstanceInfo();

    public static Person getInstance() {
        // 在方法中創建內部類
        class Student extends Person {

            @Override
            public void printInstanceInfo() {
                System.out.println("i am student");
            }
        }
        return new Student();
    }

}

public class Demo {
    public static void main(String[] args) {
        Person person = Person.getInstance();
        person.printInstanceInfo();
    }
}

 上面提到過,抽象類只是比普通類多了一些抽象方法而已,因此在抽象類也存在着構造方法,並且子類對象實例化流程和普通父子類實例化流程一致,實例化子類時也先調用父類構造方法。

 如果父類沒有無參構造,那麼子類構造必須使用super明確指出使用父類哪個構造方法。

 看下面的例子:

abstract class A{

    public A(){ // 3.調用父類構造
        this.print() ; // 4.調用被子類覆寫的方法,這裏注意,父類方法如果被子類覆寫,那麼就會調用子類覆寫了的方法,但是如果有多個子類覆寫了不同的方法,具體調用哪個,我也不清楚
    }

    public abstract void print() ;
}

class B extends A{

    private int num = 100 ;

    public B(int num) { // 2.調用B的構造方法
        super() ; // 3.子類的構造方法第一行會隱式調用父類的無參構造,父類五無參構造,要指定構造方法,在super調用期間,子類的屬性並沒有得到初始化
        this.num = num ; // 7.父類的構造調用結束後,子類屬性自動裝載爲指定值,然後執行構造裏的賦值爲類中屬性初始化
    }

    @Override
    public void print() { // 5.此時子類對象的屬性還沒有被初始化,爲默認值0
        System.out.println(this.num) ; // 6. 打印子類num的默認值
    }
}

public class Demo {

    public static void main(String[] args) {
        new B(30) ; // 1.實例化B
    }
}

 值得注意的是,抽象類中也可以不定義任何的抽象方法,就與普通類沒有什麼區別,但是就算這樣,抽象類也不能直接進行實例化。

 java中有一個關鍵字final,當它聲明類時,表示不允許該類存在子類,而抽象類必須有子類,所以,final也不能用來修飾抽象類。

 抽象類也分爲內部抽象類和外部抽象類。可以用static修飾內部類,表示該內部類爲外部類。但是不能用static修飾外部類。

 抽象類的作用在於強制規定了子類的實現結構,主要用於模板設計模式中。

 抽象類在實際的使用過程中會定義一些固化的模式,它只能接收幾種特定的指令,但是每種指令的具體實現由子類完成,父類只給出了行爲的約定。最具有代表性的就是javaweb的Servlet。

 抽象類雖然定義了子類必須要做的事情,但是抽象類依然會有單繼承侷限。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章