Java學習筆記--繼承和多態(中),java學習筆記
1.通過繼承來開發超類(superclass)
2.使用super 關鍵詞喚起超類的構造方法
3.在超類中覆蓋方法
4.區分override和overload
5.在Object類中探索toString()類
6.發現多態性和動態綁定
7.描述解釋為什麼向下轉型是必須的
8.在Object類中探索equals 方法
9.儲存,取回,實現ArrayLis的對象
10.使用ArrayList類實現Stack
11.超類中使用資料和方法,protected
12.使用final模組來禁止類和方法的覆蓋
5.在Object類中探索toString()類
Java中的每個類都是從java.lang.Object類中擴充出來,定義類的時候如果沒有特別規定是繼承來的,那麼預設父類是Object。例如
public class ClassName 和 public classClassName extends Object
這兩個語句是一樣的,String類,StringBuilder類都來是來自與Object類,學習toString()方法
public String toString()
toString的傳回值是描述對象的字串。預設情況下,返回的字串由一系列對象的類名,通常我們在使用的時候需要將toString改寫。
筆記:也可以使用對象來喚起 System.out.println(Object)或者 System.out.println(Object)
6.發現多態性和動態綁定
物件導向的三個特性:封裝、繼承和多態。
介紹兩個有用的術語:衍生類別subtype和超類supertype。子類定義的類型是subtype,例如原本研究圓是幾何體。Circle is a geometry。所以說GeomericObject類是父類,Circle是子類,所以Circle是GeomericObject的subtype。GeomericObject是Circle的supertype。
繼承關係使得子類從父類中繼承一些父類的特徵並且加入新的特性,子類是某種特殊的父類,子類的所有執行個體也可以算是父類的執行個體,反之不成。也就是我們理解的圓是幾何圖形但是幾何圖形不是圓。
動態綁定
超類中定義方法,然後在子類中進行覆蓋,就像前面的toString()方法在Object類中已經定義了,在GeometricObject中再寫一個方法方法進行覆蓋,按照如下的代碼:
Object O = new GeometricObject;System.out.println(o.toString());
上面的例子中o調用的方法是哪個的toString()。為了研究這個問題,可以想到兩個方面。比如說我們日常生活中,常常會聲明“xxx是xxx,做出某某聲明,但是實際上的是???”
出現某些事情影響到某機構,然後會有官方聲明。所以就是兩個方面,聲明xxx,實際上xxx,Java中的思想,就是declare type和actual type就是宣告類型和實際類型,變數必須聲明一個類型變數的類型叫做它的宣告類型,上面例子中的O的類型就是Object,如果遇到實際類型,實際類型根據變數的類進行參考,因此O的實際的類型是GeometricObject類,這就是動態綁定。(動態系統?聲明一個類,然後具體由它的子類極性實現,產生的對象根據具體情況下的子類進行產生,此時對象和子類綁定起來)以後在遇到很多個物件都是由不同的子類產生的,這些對象分別綁定了它的類:
7.描述解釋為什麼向下轉型是必須的
前面用的例子用比較專業的術語而言就是轉型,將某種xxx類型轉為下一類型,將某個變數從最初的類型轉為實際的類型。將某個對象轉為實際使用時候的對象。就像前面寫的語句: Object o = new student();就是隱式類型轉換,在C語言中也有這種類型轉換,比如我們以前遇到的 int a = (int) b;某種類型轉換。同樣的賦值操作,如果說是數值的賦值操作 a=b;進行類比 有沒有對象的類似賦值的操作 student b = o; 此時就出錯了。很像前面提到的"XXX是XXX"的一種關係,而且這種關係無法復原。
考慮以下的例子
object myObject = new Circle(); if(myObject instanceof Circle){ System.out.println("The Circle diameter is "+((circle)myObject).getDiameter()); ...}
myObject 變數聲明的時候是Object類,宣告類型決定了哪種方法會在編譯的時候匹配,使用myObject.getDiameter()將會造成編譯錯誤,因為Object類並沒有getDiameter方法。編譯的時候編譯器找不到匹配的方法,所以要告訴編譯器xxx是xxX的具體執行個體。為了更好理解轉型,可以按照一下的想法進行思考:水果:蘋果和橘子, fruit --superclass , Apple --subclass, Orange --subclass,Apple 是水果,所以能夠安全地使用fruit的變數,然而fruit不是水果,所以在使用的時候要隱式類型轉換。
8.在Object類中探索equals 方法
Object 類中也有equals的方法:文法如下
public boolean equals(Object o);
使用的時候:
object1.equals(object2);
預設的實現為:
public boolean equals(Object obj){ return (this == obj); }
這個實現過程檢查兩個形參變數是否指向相同對象,此時使用的是==,在自己寫的類中也可以進行重定義。
筆記:
==符號適用與比較兩個最初的資料類型,確定兩個變數是否有相同的參考,equals方法是為了測試兩個對象是否有相同的內容。==操作符的優先順序高於equals方法,因為==是檢查是否指向相同的對象。
注意:
在子類中使用 equals(SomeClassName obj)(也就是 equals(Circle c))來覆蓋是常見的錯誤,具體使用在以後的筆記中會涉及到。