第十一章 物件導向技術(選做題15+)
11.1 基本概念
物件導向=物件+分類+繼承+透過訊息的通訊
-
物件
在物件導向的系統中,物件是基本的執行實體,它既包括資料(屬性),也包括作用於資料的操作(行為),所以一個物件把屬性和行為封裝為一個整體。從程式設計者角度看,物件是一個程式模組,從使用者角度看,物件為他們提供了所希望的行為。在物件內的操作通常叫作方法。一個物件通常可由物件名、屬性和操作3部分組成。 -
訊息
物件之間進行通訊的一種構造叫作訊息。當一個訊息傳送給某個物件時,包含要求接收物件去執行某些活動的資訊,接收到訊息的物件經過解釋,然後予以響應,這種通訊機制叫作訊息傳遞。傳送訊息的物件不需要知道接收訊息的物件如何對請求予以響應。 -
類
一個類定義了一組大體上相似的物件,一一個類所包含的方法和資料描述一組物件的共同行為和屬性。類是在物件之上的抽象,物件是類的具體化,是類的例項。 -
繼承
繼承是父類和子類之間共享資料和方法的機制。這是類之間的一種關係, 在定義和實現一個類的時候,可以在一個已經存在的類的基礎上來進行,把這個已經存在的類所定義的內容作為自己的內容,並加入若干新的內容。
一個父類可以有多個子類,這些子類都是父類的特例,父類描述了這些子類的公共屬性和操作。一個子類可以繼承它的父類中的屬性和操作,這些屬性和操作在子類中不必定義。子類中還可以定義自己的屬性和操作。 -
多型
不同的物件收到同一訊息可以產生完全不同的結果,這一現象叫作多型。在使用多型的時候,使用者可以傳送一個通用的訊息,而實現的細節則由接收物件自行決定,這樣,把具有通用功能的訊息存放在高層次,而把不同的實現這一功能的行為放在較低層次,在這些低層次上生成的物件能夠給通用訊息以不同的響應。
11.2 設計原則
- 單一職責原則:設計目的單一的類。
- 開放—封閉原則:對擴充套件開放,對修改封閉。
- 李氏(Liskov)替換原則:子類可以替換父類。
- 依賴倒置原則:要依賴於抽象,而不是具體實現:針對介面程式設計,不要針對實現程式設計。
- 介面隔離原則:使用多個專門的介面比使用單一的總介面要好。
- 組合重用原則:要儘量使用組合,而不是繼承關係達到重用的目的。
- 迪米特(Demeter)原則:一個物件應當對其他物件有儘可能少的瞭解,
11.3 設計模式的概念與分類
設計模式:主要關注軟體系統的設計,與具體的實現語言無關
設計模式一般有以下4個要素:
- 模式名稱。用一兩個詞來描述模式的問題、解決方案和效果。設計模式允許在較高的抽象層次上進行設計。
- 問題。描述了應該在何時使用模式。它解釋了設計問題和問題存在的前因後果,可能描述了特定的設計問題,如怎樣用物件表示演算法等;也可能描述了導致不靈活設計的類或物件結構。
- 解決方案。描述了設計的組成成分、它們之間的相互關係及各自的職責和協作方式。模式就像一個模板,提供設計問題的抽象描述和怎樣用一個具有一般意義的元素組合(類或物件組合)來解決這個問題。
- 效果。描述了模式應用的效果及使用模式應權衡的問題。
設計模式的分類:
11.4 建立型模式
建立型模式抽象了例項化過程。它們幫助一個系統獨立於如何建立、組合和表示它的那些物件。一個類建立型模式使用繼承改變被例項化的類,而一個物件建立型模式將例項化委託給另一個物件。
建立型模式中有兩個不斷出現的主旋律。第一,它們都將關於該系統使用哪些具體的類的資訊封裝起來。第二,它們隱藏了這些類的例項是如何被建立和放在一起的整個系統關於這些物件所知道的是由抽象類所定義的介面。
因此,建立型模式在為什麼被建立,誰建立它,它是怎樣被建立的,以及何時建立這些方面給予了很大的靈活性。它們允許用結構和功能差別很大的“產品”物件配置一個系統。配置可以是靜態的(即在編譯時指定),也可以是動態的(在執行時指定)。
設計模式名稱 | 簡要說明 |
---|---|
抽象工廠模式(Abstract Factory) | 提供一個介面,可以建立一系列相關或相互依賴的物件,而無需指定它們具體的類 |
構建器模式(Builder) | 將一個複雜類的表示與其構造相分離,使得相同的構建過程能夠得出不同的表示 |
工廠方法模式(Factory Method) | 定義一個建立物件的介面,但由子類決定需要例項化哪一個類。工廠方法使得子類例項化的過程推遲 |
原型模式(Prototype) | 用原型例項指定建立物件的型別,並且透過複製這個原型來建立新的物件 |
單例模式(Singleton) | 保證一個類只有一個例項,並提供一個訪問它的全域性訪問點 |
11.5 結構型模式
結構型模式涉及如何組合類和物件以獲得更大的結構,結構性模式採用繼承機制來組合介面或實現。
結構型物件模式不是對介面和實現進行組命,而是描述瞭如何對一些物件進行組合,從而實現新功能的一些方法。
11.6 行為型模式
行為模式涉及演算法和物件間職責的分配。行為模式不僅描述物件或類的模式,還描述它們之間的通訊模式。這些模式刻畫了在執行時難以跟蹤的複雜的控制流。它們將使用者的注意力從控制流轉移到物件間的聯絡方式上來。
行為類模式使用繼承機制在類間分派行為,主要有Template Method(模板方法)和Interpreter(直譯器)兩種模式。
行為物件模式使用物件複合而不是繼承。一些行為物件模式描述了一組對等的物件怎樣相互協作以完成其中任一個物件都無法單獨完成的任務。其他的行為物件模式常將行為封裝在一個物件中並將請求指派給它。
11.7 java程式設計
優點:
- 跨平臺。
- 程式碼可移動(與html相結合)。
- 完全物件導向。
- 編出來的程式不易出錯(沒有指標,記憶體垃圾自動回收,不會產生記憶體洩露)
此外,還有簡單、安全、多執行緒等優點。
Java與C++的區別:
- 完全物件導向:無全域性變數、無結構和聯合、自動回收記憶體垃圾。
- 沒有指標。
- 沒有多繼承。
- 解釋執行。
11.7.1 基本語法
11.7.2 類
一個類是一些屬性和方法的封裝體,類的定義用關鍵字class宣告,用關鍵字public、protected、private指定類的成員的存取控制屬性:
private(私有)成員
,只有類內部的方法才能訪問;
protected(保護)成員
,可被派生類和同一資料夾下的類訪問;
public(公有)成員
,可以從類的外部訪問。
預設是public。這體現了物件導向的以下指導思想:儘量將類內部的細節隱藏起來,對類的屬性的操作應該透過類的方法來進行。
11.7.3 繼承
Java中用關鍵字extends
表示類間的繼承關係。
父類的公有屬性和方法成為子類的屬性和方法,子類如果有和父類同名、同引數型別的方法,那麼子類物件在呼叫該方法時,呼叫的是子類的方法,亦即方法的重置。如果想要呼叫父類的同名方法,需要用super
關鍵字(屬性同理)。
子類的物件可以作為祖先類的物件使用,即所謂類的向上轉換,反之則不行。具體表現在可以用子類物件來對祖先類物件賦值,可以用子類物件作為實參去呼叫以父類物件為形參的函式。
11.7.4 過載
同一個類中的兩個或兩個以上方法,名字相同,而引數個數不同或引數型別不同,叫作過載。
注意:方法名字和引數都一樣,而僅僅返回值型別不同,這不是過載。
11.7.5 靜態屬性和靜態方法
靜態屬性和靜態方法的宣告用關鍵字static
實現。一個類的靜態屬性只有一個,由所有該類的物件共享。不需要建立物件也能訪問類的靜態屬性和方法,訪問方式為類名.靜態屬性或靜態方法
。靜態方法與物件無關,因此不能在靜態方法中訪問非靜態屬性和呼叫非靜態方法。
11.7.6 this、super、final
this代表當前物件,super代表當前物件的父類
this的主要用途有:
- 一個建構函式呼叫另一個建構函式,對建構函式的呼叫必須是第一條語句。
- 將物件自身作為引數來呼叫一個函式。
super的用途:
在子類中呼叫父類的同名方法,或在子類的建構函式中呼叫父類的建構函式,此時也必須是第一條語句。
final:
用final關鍵字定義的常量,在其初始化或第一次賦值後,其值不能被改變。常量必須先有值,然後才能使用。對於常量的第一次賦值只能在建構函式中進行。
final物件的值不能被改變,指的是該物件不能再指向其他物件,而不是指不能改變當前物件內部的屬性值。
函式引數宣告為final後,函式中的值不能改變。
final方法是不能被重置的方法。
final類不能被繼承,其所有方法都是fina的,但屬性可以不是final的。
11.7.7 抽象類和介面
-
抽象類
抽象類透過關鍵字abstract
實現,抽象類的目的是定義一個框架,規定某些類必須具有的一些共性。包含抽象方法的類一定是抽象類,所謂抽象方法是指沒有函式體的方法。抽象類的直接派生類必須實現其抽象方法,抽象類只能用於繼承,不能建立物件。 -
介面
介面用關鍵字interface
宣告,只能用於繼承。注意此時關鍵字為implements
(實現)。介面用於替代多繼承的概念,能實現多繼承的部分特點,又避免了多繼承的混亂,還能起到規定程式框架的作用。注意:介面也可以用於多型。直接繼承了介面的類,必須實現介面中的抽象方法,間接的則可以實現,也可以不實現。 -
抽象類與介面的異同
介面和抽象類都不能建立物件
抽象類不能參與多繼承,抽象類可以有非靜態的成員變數,可以有非抽象方法
介面可以參與多繼承,所有屬性都是靜態常量,所有方法都是public抽象方法。