菜鳥成長系列-物件導向的四大基礎特性

glmapper發表於2017-11-05

按照之前的學習規劃,開始進行第一部分的學習。那麼今天就重新認識一下JAVA中的四大特性:抽象、封裝、繼承、多型

抽象

學習物件導向,抽象還是很重要的。物件導向最接近我們人類的思維,你的抽象能力就是你對萬物萬事總結和歸納的能力。關於抽象,就是從具體事物抽出、概括出它們共同的方面、本質屬性與關係等,而將個別的、非本質的方面、屬性與關係捨棄,這種思維過程,稱為抽象。在JAVA中表現就是使用abstract來修飾類,被abstract修飾的類成為抽象類,一般是為了為子類提供一些共有的屬性和行為,不同的子類根據自身的特性再進行具體的行為實現。

封裝

封裝是物件導向的重要原則,就是把物件的屬性和行為(方法)結合為一個獨立的整體,並儘可能隱藏物件的內部實現細節;在java中,對於物件的內部屬性一般用private來實現隱藏,並通過set和get方法對外提供訪問介面。封裝實際上是一種資訊隱藏技術的實現方式。

  • 物件的資料封裝特性徹底消除了傳統結構方法中資料與操作分離所帶來的種種問題,提高了程式的可複用性和可維護性,降低了程式設計師保持資料與操作內容的負擔。
  • 物件的資料封裝特性還可以把物件的私有資料和公共資料分離開,保護了私有資料,減少了可能的模組間干擾,達到降低程式複雜性、提高可控性的目的。

例如:對於客觀存在的人這個物件進行屬性和行為抽象【此處僅僅是部分抽象】;使用private關鍵字來修飾人的屬性,並通過對應的set和get方法對外界提供訪問入口;在行為方面,通過public關鍵字來修飾,對外提供具體的行為描述。外界物件並不知道“人”這個物件在內部發生了什麼,僅僅是通過提供的方法來獲得具體的描述資訊。

/**
 * 人
 * @author glmapper
 *
 */
public class Person {
    //姓名
    private String name;
    //年齡
    private int age;
    //性別
    private String sex;
    //身高
    private float high;
    //體重
    private float weight;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public float getHigh() {
        return high;
    }
    public void setHigh(float high) {
        this.high = high;
    }
    public float getWeight() {
        return weight;
    }
    public void setWeight(float weight) {
        this.weight = weight;
    }


    public void eat(){
        System.out.println("吃東西");
    }

    public void walk(){
        System.out.println("走路");
    }

    public void study(){
        System.out.println("學習");
    }
}複製程式碼

繼承

繼承是物件導向最顯著的一個特性,是從已有的類中派生出新的類,我們把它稱之為子類,子類繼承父類的屬性和行為,並能根據自己的需求擴充套件出新的屬性和行為,提高了程式碼的可複用性。

  • 提高了程式碼的複用性。
  • 讓類與類之間產生了關係,給第三個特徵多型提供了前提。

Java的繼承通過extends關鍵字來實現,實現繼承的類被稱為子類,被繼承的類稱為父類(有的也稱其為基類、超類),父類和子類的關係,是一種一般和特殊的關係;子類擴充套件父類,將可以獲得父類的全部屬性和方法。

男人是人的一種,男人的特徵是有鬍子,因此也有剪鬍子的行為【有鬍子和剪鬍子並非依賴關係;一個是屬性,一個是行為】;但是男人繼承了人這個父類,因此,男人也具有例如姓名、性別、身高、體重等屬性,同時也具有父類人具有的吃飯、走路和學習的行為。

/**
 * 男人
 * @author glmapper
 *
 */
public class Man extends Person{
    //鬍子
    private String  goatee;

    public String getGoatee() {
        return goatee;
    }

    public void setGoatee(String goatee) {
        this.goatee = goatee;
    }

    public void shaved(){
        System.out.println("剪鬍子");
    }
}複製程式碼

重寫父類的方法:
大部分的時候,子類總是以父類為基礎,額外新增新的屬性和方法。但有一種情況例外:子類需要重寫父類的方法。例如男人吃東西比較快,女人吃東西比較慢,因此對於eat方法來說,Man可以覆蓋父類的eat方法,來描述Man本身的特點。

@Override
public void eat(){
    System.out.println("快速的吃東西");
}複製程式碼

當子父類中出現相同方法時,會先執行子類中的方法。
重寫的特點:方法名一樣,訪問修飾符許可權不小於父類,返回型別一致,引數列表一致。

多型

定義:指允許不同類的物件對同一訊息做出響應。即同一訊息可以根據傳送物件的不同而採用多種不同的行為方式。(傳送訊息就是函式呼叫)
實現多型的技術稱為:動態繫結(dynamic binding),是指在執行期間判斷所引用物件的實際型別,根據其實際的型別呼叫其相應的方法。從語言特點上來說,Java引用變數有兩個型別:一個是編譯時型別,一個是執行時型別。編譯時的型別由宣告該變數時使用的型別決定,執行時的型別由實際賦給該變數的物件決定。如果編譯時型別和執行時型別不一致,就會出現所謂的多型(Polymorphism)。
封裝和繼承都是為Java語言的多型提供了支撐;多型存在的三個必要條件:

  • 要有繼承;
  • 要有重寫;
  • 父類引用指向子類物件。

具體的實現方式就是:介面實現,繼承父類進行方法重寫,同一個類中進行方法過載。

下一篇在說類和介面的時候再用具體的例子來描述覆蓋、過載。

相關文章