Java面向對象核心知識(二)
文章目錄
一、方法的重寫(overwrite/override)
- 在子類中可以根據需要從父類中繼承來的方法進行重寫
- 重寫方法必須要和被重寫方法具有相同的方法名稱、參數列表和返回值類型。
- 重寫方法不能使用比被重寫方法更嚴格的訪問權限。
- 當需要重寫一個方法時,要去copy,以免出錯!
- 重寫和重載的區別。方法重新實現了動態多態性(也稱爲動態聯編),方法重載則實現了靜態多態性(編譯時多態)。也正是重寫和重載體現了Java的多態性。
二、super關鍵字
在Java類中使用super來引用父類的東西
- 當new一個對象出來的時候會有一個this引用,這個this指向這個對象自身。
- 如果這個對象是一個子類對象的話,那麼,還會有另外的一個引用,叫super,super指向當前對象裏面的父對象。
- 使用super.方法名調用父類中的方法
- 一個子類對象new出來的時候,在這個子類對象內部是有一個父類對象的。
三、繼承中的構造方法
- 在子類的構造過程中必須調用其父類的構造方法,或者說必須在子類中重寫構造方法,因爲構造方法不能繼承。
- 子類可以在自己的構造方法中使用super(參數列表)調用其父類的構造方法;使用this(參數列表)調用本類的另外的的構造方法,如果調用super,則必須寫在子類構造方法的第一行。
- 如果子類的構造方法中沒有顯式調用父類的構造方法,則系統默認使用父類無參數構造方法。
- 如果子類構造方法中既沒有顯式調用父類構造方法,而父類中又沒有無參的構造方法,則編譯出錯!
四、Object類
- Object類是所有Java類的根基類
- 如果在類的聲明中未使用extends關鍵字指明父類,則默認父類爲Object類
例如:
public class Person{
....
}
等價於
public class Person extends Object{
....
}
五、toString方法(Object中其中的一個方法)
- Object類中定義有public String toString()方法,其返回值是String類型,此方法用於描述當前對象的有關信息,默認描述格式:類名加其所在的內存地址(類@地址)
- 在進行String與其他類型數據的連接操作時,將自動調用該對象的toString()方法,例如:
System.out.println("info" + person);
- 可以根據需要在用戶自定義類型中重寫toString()方法。
- 補充:“==”比較的是兩個對象的內存地址,而equals則比較的是二者是否指向同一個對象。
六、equals方法(也是Object類中的一個方法)
- Object類中定義有:
public boolean equals(Object obj)
方法,提供定義對象是否“相等”
的邏輯。 - Object的equals方法定義爲:x.equals(y),當x和y是同一個對象的引用時返回true,否則返回false。
- JDK提供的一些類,如String,Date等,重寫了Object的equals方法,調用這些類的equals方法,x.equals(y),當x和y所引用的對象是同一類對象且屬性內容相等時(並不一定是相同對象),返回true,否則返回false。
- 可以根據需要在用戶自定義類型中重寫equals方法。
七、對象轉型(casting)—— 程序的可擴展性得到了很大的提高
- 一個父類的引用類型變量可以“指向”其子類的對象。(如:
Father father = new Son();
) - 一個父類的引用不可以訪問其子類對象新增加的成員變量和方法。
- 可以使用引用變量instanceof類名來判斷該引用類型變量所“指向”的對象是否屬於該類或者該類的子類。
- 子類的對象可以當作父類的對象來使用,稱作向上轉型(upcasting),反之稱爲向下轉型(downcasting)。
- 父類引用指向子類對象時,它看到的只是作爲父類的那部分所擁有的屬性和方法,至於子類那部分是“看”不到的,但是它仍屬於子類類型。例如:
animal instanceof Dog; //true
- 在發生向下轉型之前,一定要首先發生對象的向上轉型,建立關係後纔可以進行。例如:
Animal animal = new Dog("bigyellow","yellow"); //通過向上轉型建立關係
Dog dog1 = (Dog) animal; //向下轉型
System.out.println(dog1.furColor);
- 父類引用可以指向子類對象,從而程序可擴展性得到了很大的提高,我們可以在一個方法參數裏面定義父類的引用,然後實際傳的時候是子類對象,這個時候在實現方法時,判斷到底屬於哪個子類,然後再執行裏面的方法或者調用裏面的成員變量。
八、動態綁定(多態)—— 程序的可擴展性達到極致
- 動態綁定是指“在執行期間(非編譯期間)”判斷所引用對象的實際類型,根據實際的類型調用其相應的方法。new出來的是誰,就找誰的方法。
- 下面的例子中,根據Lady對象的成員變量pet所引用的不同的實際類型而調用相應的enjoy方法。
package com.lfq.faceobject.testcast;
/**
* 多態(動態綁定)
* 程序的可擴展性發展到極致
*/
public class TestDuoTai {
public static void main(String[] args) {
Cat2 cat2 = new Cat2("cat2Name", "blue");
Dog2 dog2 = new Dog2("dog2Name", "black");
Lady lady1 = new Lady("laydy1", cat2);
Lady lady2 = new Lady("lady2", dog2);
lady1.mypetEnjoy();
lady2.mypetEnjoy();
}
}
class Animal2 {
private String name;
Animal2(String name) {
this.name = name;
}
public void enjoy() {
System.out.println("叫聲......");
}
}
class Cat2 extends Animal2 {
private String eyesColor;
Cat2(String name, String eyesColor) {
super(name);
this.eyesColor = eyesColor;
}
public void enjoy() {
System.out.println("貓叫聲......");
}
}
class Dog2 extends Animal2 {
private String furColor;
Dog2(String name, String furColor) {
super(name);
this.furColor = furColor;
}
public void enjoy() {
System.out.println("狗叫聲......");
}
}
class Lady {
private String name;
private Animal2 pet;
Lady(String name, Animal2 pet) {
this.name = name;
this.pet = pet;
}
public void mypetEnjoy() {
pet.enjoy();
}
}
程序運行結果如下:
核心機制:調用方法時,只要這個方法重寫了,實際調用哪個方法,要看你實際當中new的是什麼對象,這個機制就叫多態機制或者動態綁定,也稱爲延遲綁定,這個機制是面向對象的核心機制。
-
多態的總結
多態的存在必須的三個條件:- 要有繼承或者類實現接口
- 要有重寫或者對接口方法的實現
- 父類引用指向子類對象或者接口對象指向它的實現類
這三個條件一旦滿足,當你調用父類裏面被重寫的方法或者調用你實現接口的方法的時候,實際當中new的是哪個子類對象就調用子類對象的那個方法。
九、抽象類
- 繼承抽象類的類一般應該實現抽象類中的所有抽象方法,如果沒有,那麼該子類也應該聲明爲抽象類。
- 用abstract關鍵字來修飾一個類時,這個類叫做抽象類,用abstract來修飾一個方法時,該方法叫做抽象方法。
- 含有抽象方法的類必須被聲明爲抽象類,抽象類必須被繼承,抽象方法必須被重寫。
- 抽象類不能被實例化,即不能new對象
- 抽象方法只需聲明,而不需要實現。
- 抽象方法就是被用來重寫的,所以在子類裏面應該重寫這方法。
- 抽象方法的一個主要目的就是爲所有子類定義一個統一的接口。
- 抽象類不一定要包含抽象方法。若類中包含了抽象方法,則該類必須被定義爲抽象類。
- 抽象類的子類必須覆蓋所有的抽象方法後才能被實例化,否則這個子類還是個抽象類。
十、final關鍵字
- final的變量的值不能夠被改變,包括final的成員變量,final的局部變量。例如:形式參數
- final的類不能夠被繼承,即不能有子類。
- final的方法不能夠被重寫。
- final常量:常量必須賦初值,即初始化可在定義處或構造方法中,而且不能再發生變化。
十一、接口(interface)
- 接口是抽象方法和常量值的定義的集合。。
- 從本質來講,接口是一種特殊的抽象類,這種抽象類中只包含常量和方法的定義,而沒有變量和方法的實現。
- 接口定義,例如:
public interface Runner{
public static final int id = 1;
public abstract void start();//public和abstract寫不寫都行,默認就是public和abstract的
public void run();
public void stop();
}
- 多個無關的類可以實現同一個接口。
- 一個類可以實現多個無關的接口。
- 與繼承關係類似,接口與實現類之間存在多態性
- 定義Java類的語法格式:
<modifier> class <name> [extends <superclass>] [implements <interface>] [,<interface>...]{
<declarations>*
}
接口特性:
- 接口可以多重重現,也就是一個類可以實現多個接口。
- 接口中聲明的屬性默認爲public static final的,也只能是public static final的。
- 接口中只能定義抽象方法,而且這些方法默認爲public的,也只能是public的。
- 接口可以繼承其他的接口,並添加新的屬性和抽象方法。
- 接口之間可以相互繼承,一個類只能實現接口,類和類之間可以繼承,接口和接口之間也可以相互繼承,但是類和接口之間,只能是類實現接口。
十二、總結
- Java程序運行的內存分析至關重要
- 對象和類的概念
- 類和類之間的關係,類和對象之間的關係
- 面向對象設計思想
- class
- new和引用的概念;構造方法的概念
- 方法重載;構造方法重載
- this
- static
- package和import
- private/default/protected/public
- extends
- overwrite/override
- final
- Object toString/equals
- upcasting/downcasting
- 多態