java面向對象繼承與多態介紹

一.概述  

        面向對象程序設計的三大原則是封裝性,繼承性和多態性。繼承性是子類自動共享父類的數據和方法的機制,它是由類的派生功能體現的。繼承具有傳遞性,使得一個類可以繼承另一個類的屬性和方法,這樣通過抽象出共同的屬性和方法組件新的類,便於代碼的重用。而多態是指不同類型的對象接收相同的消息時產生不同的行為,這裡的消息主要是對類成員函數的調用,而不同的行為是指類成員函數的不同實現。當對象接收到發送給它的消息時,根據該對象所屬的類,動態選用在該類中定義的實現算法。

二.繼承

2.1 繼承的概述

在現實中存在很多如圖所示的關系:

       出租車,卡車和公交車都是汽車的一種,分別擁有相似的特征。例如,引擎的數量,外觀顏色等。它們擁有相似的行為,如剎車和加速的功能。但是每種不同的交通工具又有自己的特征,如公交車擁有和其他交通工具不同的特性和行為——最大載客數量和到指定站點要報站的特點,而卡車的主要功能是送貨物,也就是載貨和卸貨,因此擁有最大載重量的特性。

       在面向對象的程序設計中該怎樣描述現實世界的這種狀況呢?這就用到繼承的概念。

       所謂繼承,就是從已有的類中派生出新的類,新的類能吸收已有類的數據屬性和行為,並能擴展新的能力。已有的類一般稱為父類(基類或超類),這個過程也稱為類的派生。由基類產生的新類稱為派生類或子類,派生類同樣可以作為基類再派生新的子類,這樣就形成瞭類間的層次結構。

       基類和派生類類的關系如下:

       * 基類是派生類的抽象(基類抽象瞭派生類的公共特征)。

       * 派生類是對基類的擴展。

       * 派生類和基類的關相當於“是一個(is a)”的關系,即派生類是基類的一個對象,而不是“有(has)”的關系,即類的對象包含一個或多個其他類的對象作為該類的屬性。

2.2 繼承機制

       定義教師類,其中一類教師為Net教師,屬性為姓名,所屬部門,方法為授課,自我介紹。

public class NetTeacher {
   private String name;
   private String school;
   public NetTeacher(String myName,String mySchool){
      name = myName;
      school = mySchool;
   }
   public void giveLession(){
      System.out.println("啟動 VS2021 ");
      System.out.println("知識點講解");
      System.out.println("總結提問");
   }
   public void introduction(){
      System.out.println("大傢好!我是" + schoool + "的" + name + " 。");
   }
}

       定義教師類,其中一類教師為Java教師,屬性為姓名,所屬部門,方法為授課,自我介紹。

public class JavaTeacher {
   private String name;
   private String school;
   public JavaTeacher(String myName,String mySchool){
      name = myName;
      school = mySchool;
   }
   public void giveLession(){
      System.out.println("啟動 IDEA2021 ");
      System.out.println("知識點講解");
      System.out.println("總結提問");
   }
   public void introduction(){
      System.out.println("大傢好!我是" + schoool + "的" + name + " 。");
   }
}

       在程序處理中,發現兩個類的定義非常相似,有很多相同點,如教師的屬性姓名,所屬部門類似,類的方法也基本相同。

       針對這種情況,將Java教師類和Net教師類的共性抽取出來,形成父類Teacher類,使得Net教師和Java教師成為Teacher類的子類,則子類繼承父類的基本屬性和方法,就簡化瞭子類的定義。上述代碼可以修改如下:

public class Teacher {
   private String name;
   private String school;
   public Teacher(String myName,String mySchool){
      name = myName;
      school = mySchool;
   }
   public void giveLession(){
      System.out.println("知識點講解");
      System.out.println("總結提問");
   }
   public void introduction(){
      System.out.println("大傢好!我是" + schoool + "的" + name + " 。");
   }
}
 
子類JavaTeacher:
public class JavaTeacher extends Teacher {
   public JavaTeacher(String myName,String mySchool){
      super(myName,mySchool);
   }
   public void giveLession(){
      System.out.println("啟動 IDEA2021 ");
      super.giveLession;
   }
 
子類NetTeacher:
public class NetTeacher extends Teacher {
   public NetTeacher(String myName,String mySchool){
      super(myName,mySchool);
   }
   public void giveLession(){
      System.out.println("啟動 VS2021 ");
      super.giveLession;
   }

       子類自動繼承父類的屬性和方法,子類中不再存在重復代碼,從而實現代碼的重用。

       通過關鍵字 extends,分別創建父類 Teacher 的子類 JavaTeacher 和 NetTecher 。子類繼承父類所有的成員變量和成員方法,但不能繼承父類的構造方法。在子類的構造方法中,可使用語句super (參數列表)調用父類的構造方法,如子類構造方法中的語句 super(myName,mySchool)。

       extends 說明要構建一個新類,該類從已存在的類派生而來。派生的定義過程,實際是經歷瞭以下幾個過程:

       *子類繼承父類中被聲明為 public 和 protected 的成員變量和成員方法,但是不能繼承被聲明為 private 的成員變量和成員方法。

       *重寫父類成員,包括數據成員和成員函數。如果子類聲明瞭一個與父類成員函數相同的成員函數,子類中的新成員則屏蔽瞭父類同名成員,類似函數中的局部變量屏蔽瞭全局變量,稱為同名覆蓋(Overriding)。

       *定義新成員。新成員是派生類自己的新特性。派生類新成員的加入使得派生類在功能上有所發展。

       *必須在派類中重寫構造方法,因為構造方法不能繼承。

2.3 類中屬性,方法的繼承與覆蓋

1.屬性的繼承與覆蓋

       子類可以繼承父類的所有非私有屬性。

       子類也可以覆蓋繼承的成員變量,對於子類可以從父類繼承的成員變量,隻要子類中定義的成員變量和父類中的成員變量同名,子類就覆蓋瞭繼承的成員變量。

       當子類執行它自己定義的方法時,所操作的就是它自己定義的數據成員,,從而覆蓋父類繼承來的數據成員。

2.方法的繼承與覆蓋

       父類中非私有( private )方法可以被子類所繼承。

       在子類繼承父類的成員方法時,應註意一下兩項:

       *子類不能訪問父類的 private 成員方法,但子類可以訪問父類的 piblic ,protected 成員方法。

       *訪問 protected 時,子類和同一包內的方法都能訪問父類的 protected 成員方法,但其他方法不能訪問。

       方法的覆蓋是指子類中定義一個方法,並且這個方法的名字,返回類型,參數列表與父類繼承的方法完全相同。

2.4 super 關鍵字

       子類不能繼承父類的構造方法。

       如果基類中沒有默認構造方法或希望調用帶參數的基類構造方法,要使用關鍵字 super 來顯示調用基類構造方法。使用關鍵字 super 調用基類構造方法的語句,必須是子類構造方法的第一個可執行語句。調用基類構造方法時,傳遞的參數不能是關鍵字 this 或當前對象的非靜態成員。

      super 關鍵字主要應用於繼承關系實現子類對父類方法的調用,包括對父類構造方法和一般方法的調用。具體使用方法如下:

       (1)子類的構造方法如果要引用 super ,必須把 super 放在構造方法的第一個可執行語句。例如:

public CommonEmployee (String name,double bonus){
   super (name);                         //通過 super () 的調用,給父類的數據成員賦初值
   this.bonus = bonus;                   // this 指當前對象
   System.out.println("子類構造方法的調用");
}

       (2)在 Java 中,有時還會遇到子類中的成員變量或方法與父類中的成員變量或方法同名。同名子類中的成員變量或方法名優先級高,所以子類中的同名成員變量或方法覆蓋瞭父類的成員變量或方法,但是我們如果想要使用父類中的這個成員變量或方法,就需要用到 super .

       (3)可以用 super 直接傳遞參數。見下面代碼:

public class Person {
    Person(){
        prt("A Person.");
    }
    Person(String name){
        prt("A person name is:" + name);
    }
    public static void prt(String s){
        System.out.println(s);
    }
}
 
public class Chinese extends Person {
    Chinese(){
        super();                     //調用父類無形參構造方法
        prt("A chinese");         //調用父類的方法prt
    }
    Chinese(String name){
        super(name);                 //調用父類具有相同形參的構造方法
        prt("his name is:" + name);
    }
    Chinese(String name,int age){
        this(name);                  //調用當前具有相同形參的構造方法
        prt("his age is:" + age);
    }
 
    public static void main(String[] args) {
        Chinese cn = new Chinese();
        cn = new Chinese("Kevin");
        cn = new Chinese("Jhone",21);
    }
}

 程序分析如下:

       ●main()中首先構建Chinese的第一個對象cn, 語句cn = new Chinese()調用子類無參的構造方法Chinese(),在構造方法中super()語句調用父類的無參構造方法Person(),在父類無參的構造方法中調用父類的方法prt(),程序輸出結果A Person,接下來返回子類的構造方法的調用處,繼續執行下面的語句pr("A chinese."),則調用父類的方法prt輸出結果A chinese.結束第一條語句。

       ●程序繼續執行第二條語句cn = new Chinese("kevin");此時調用子類具有一 個參數參的構造方法Chinese(name),在構造方法中super(name)語句調用父類的有參構造方法prt("A person name is:"+ name),程序輸出結果A person name is:kevin,接下來返回子類的構造方法的調用處,繼續執行下面的語句prt("his name is:"+ name),則調用父類的方法prt輸出結果his name is:kevin,結束第二條語句。

       ●接下來程序繼續執行第三條語句cn = new Chinese("Jhone,"22);程序執行時先調用子類具有兩個參數參的構造方法Chinese(name, age), 在構造方法中this ( name )語句則調用的是當前具有相同參數的構造方法,即調用子類具有一個參數參的構造方法Chinese(name),接下來調用父類的有參構造方法Person(name),為父類的name進行初始化,再接下來在父類有參的構造方法中調用父類的方法prt("A person name is:"+ name),程序輸出結果A person name is: Jhone,接下來返回子類的構造方法的調用處,繼續執行下面的語句prt("his name is:"+ name),則調用父類的方法prt輸出結果his name is: Jhone,調用結束後程序返回子類構造方法Chinese(name,age)執行語句prt("his age is:"+ age); 輸出結果his age is:22,結束第二條語句。

三. 多態

       多態是指在父類中定義的屬性和方法被子類繼承之後,可以具有不同的數據類型或表現出不同的行為,這使得同一個屬性或方法在父類及其各個子類中具有不同的含義。

       對面向對象來說,多態分為編譯時多態和運行時多態。其中編譯時多態是靜態的,主要是指方法的重載,它是根據參數列表的不同來區分不同的方法。通過編譯之後會變成兩個不同的方法,在運行時談不上多態。而運行時多態是動態的,它是通過動態綁定來實現的,也就是大傢通常所說的多態性。

       Java  實現多態有 3 個必要條件:繼承、重寫和向上轉型。隻有滿足這 3 個條件,開發人員才能夠在同一個繼承結構中使用統一的邏輯實現代碼處理不同的對象,從而執行不同的行為。

繼承:在多態中必須存在有繼承關系的子類和父類。重寫:子類對父類中某些方法進行重新定義,在調用這些方法時就會調用子類的方法。向上轉型:在多態中需要將子類的引用賦給父類對象,隻有這樣該引用才既能可以調用父類的方法,又能調用子類的方法。

總結

到此這篇關於java面向對象繼承與多態介紹的文章就介紹到這瞭,更多相關java繼承與多態內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: