Chapter3:抽象資料類型(ADT)和面向對象的程式設計(OOP)
3.4Object-Oriented Programming(OOP)面向對象的程式設計
1.object,class,attribute,method的基本概念
1.object
object為現實中的物體,有狀态和行為兩種特點。
例如:
- 狗的狀态有姓名,顔色,饑餓度。
- 狗的行為有叫,搖尾巴,撿東西。
-自行車的狀态有車輪子,車蹬子,速度。
-自行車的行為有換輪子,換車蹬子,踩刹車。
Java中将狀态稱為屬性(fields),将行為稱為方法(methods)。
2.classes
類定義了屬性(fields)和方法(methods)
Customer為類的名字,下面是屬性和方法。
類方法(class methods)和執行個體方法(instance methods)的差別.
- display()即為類方法,需在前面加static,可直接用類調用。
- show()為執行個體方法,需要建立一個執行個體對象,在執行個體對象中調用。
注意:
- 靜态方法無法調用非靜态成員(方法和變量),即調用的必須有static。
- 成員方法可以調用靜态或成員變量(即非靜态變量)。
例如:
MyStatic.staticStr中staticStr必須為靜态變量。
而main函數中聲明的執行個體變量可随意使用class中的靜态或非靜态變量。
- 成員方法在執行時才在棧中配置設定空間 。
-
而類方法在編譯時就已經在棧中配置設定空間,在執行時可直接調用。
-
2.接口(Interface)
1.接口(interface)
- Interface和Class用來定義和實作ADT。
- 接口之間可以繼承和擴充。(同樣的方法可以有相同或不同的實作)
- 一個類可以實作多個接口。
- 一個接口可以有多種實作類。
例如:
一個複數的接口。它的方法為以下8條,均沒有實作。
它的實作方法如下:
實作方法1:
使用複數的标準表示方法,即實部和虛部來表示。
實作方法2:
使用半徑和弧度來表示複數。
用戶端的應用:
可以注意到,除了實作方法和輸入資料不同以外,不同的實作有着相同的方法和結果。
為什麼要有不同的實作:
- 有不同的表現。(有快有慢)
-
有不同的行為。(在同一基礎上可以增加不同的行為)
例如:HashSet,TreeSet。
自從java8開始,接口中可以有靜态方法
3.枚舉(enumerations)
枚舉的實作方法
向枚舉中的例子中添加資料和方法。
4.封裝和資訊隐藏(Encapsulation and information hiding)
用接口隐藏資訊
- 使用接口類型聲明變量。
- 用戶端僅使用接口中定義的方法。
- 用戶端代碼無法直接通路屬性。
public,protected,default,private作用域.
private可以在不影響實用的情況下變為public,而public不能變為private。
5.繼承和重寫(Inheritance and Overriding)
1.Inheritance
嚴格繼承: 子類隻能添加新方法,無法重寫父類中的方法。
使用關鍵字 extends 進行繼承。
使用關鍵字 @Override 進行重寫。
在父類中final的方法,在子類中無法重寫。
當父類重寫函數不為空時,對于大多數子類可直接複用,而某些子類有特殊性,需要重寫。
當父類重寫函數為空時,子類全部需要重寫。
2Abstract Class(抽象類)
抽象類的特點:
- 隻有定義沒有實作。
- 抽象類不能執行個體化。
- 繼承某個抽象類的子類在執行個體化時,所有父類中的抽象方法必須已經實作。(即子類必須補全父類中的抽象方法)
三者關系:
Abstract Class implements Interface(抽象類實作接口)
Concrete class extends Abstract Class(具體類繼承抽象類)
抽象類的例子:通用方法在抽象類中實作,不通用的方法在子類中實作。
6.多态,子類型,重載(Polymorphism subtyping overloading)
1.Three Types of Polumorphism.(三種類型的多态)
- 特殊多态(Ad hoc):一個方法可以有多個同名的實作。(方法重載)
- 參數化多态(Parametric):一個類型名字可以代表多個類型。(泛型程式設計)
- 子類型多态(Subtyping):一個變量名字可以代表多個類的執行個體。(子類型)
2.特殊多态(Ad hoc polymorphism and Overloading)
重載:多個方法有同樣的名字。但有不同的參數清單或傳回值類型。
- 重載是在編譯階段時決定要具體執行哪個方法(static type checking)。
- 而重寫是在運作時進行動态檢查(dynamic checking)。
- 重寫時父類和子類中的方法具有相同的簽名。
- 簽名不同時則為重載
- 子類重載了父類的方法後,子類仍然繼承了被重載的方法。
重載的規則:
- MUST 必須有不同的參數清單
- CAN 相同/不同的傳回值類型
- CAN 相同/不同的public/private/protected
- CAN 抛出不同的異常
- CAN 可以在一個類中重載,也可在子類中重載
重載的例子:
另一個重載的例子:證明了重載是在編譯階段進行的。進行的執行個體化,以前面定義的類為準。
定義Animal類,Horse類繼承Animal類。
分别Animal animalobj=new Animal();
Horse horseobj=new Horse();
Animal animalRefToHorse= new Horse();
分别代入ua.doStuff觀察使用了重載的哪一個方法。
我們注意到最後一個animalRefToHorse列印出來的是Animal。
另一個例子:
證明了重載是在編譯時進行選擇,重寫是在運作時進行選擇。
例如Animal ah=new Horse();ah.eat();編譯時會進行判定,判定Animal類中是否有eat()方法,如果有才在運作時使用子類Horse()中的重寫用法。如果父類中沒有該方法,則直接會編譯錯誤。
3.參數化多态(Parametric polymorphism and Generic programming)
Generics(泛型)
參數多态性是指方法針對多種類型時具有同樣的行為,此時可使用統一的類型表達多種類型。
例子:
泛型接口可用非泛型或泛型的實作類。
1.非泛型的實作類
2.泛型的實作類
4.子類型多态(Subtyping Polymorphism)
子類型的規約不能弱化超類型的規約。
子類型多态:不同類型的對象可以統一的處理而無需區分。
10.一些對象的重要方法
- equals()比較的是内容是否相等
- hashCode()
- toString() 列印内容
tostring的重載
hashcode的重載