




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
面向?qū)ο蟪绦蛟O(shè)計概述近年來,面向?qū)ο蟪绦蛟O(shè)計的思想已經(jīng)被越來越多的軟件設(shè)計人員所接受。它是在吸取結(jié)構(gòu)化程序設(shè)計的一切優(yōu)點的基礎(chǔ)上發(fā)展起來的一種新的程序設(shè)計思想。這種新的思想更接近人的思維活動,人們運用這種思想進(jìn)行程序設(shè)計時,可以很大限度地提高編程能力,減少軟件維護(hù)的開銷。面向?qū)ο笙到y(tǒng)最突出的特點是封裝性、繼承性和多態(tài)性。1.1什么是面向?qū)ο蟪绦蛟O(shè)計在軟件設(shè)計和實現(xiàn)中,傳統(tǒng)的被人們廣泛使用的方法是面向過程的程序設(shè)計方法。在討論面向?qū)ο蟪绦蛟O(shè)計之前,我們需要討論一下面向過程的程序設(shè)計。1.1.1面向過程程序設(shè)計的基本概念面向過程的程序設(shè)計思想的核心是功能的分解:第一步要做的工作就是將問題分解成若干個稱為模塊的功能塊;第二步根據(jù)模塊功能來設(shè)計一系列用于存儲數(shù)據(jù)的數(shù)據(jù)結(jié)構(gòu);第三步編寫一些過程(或函數(shù))對這些數(shù)據(jù)進(jìn)行操作。顯然,這種方法將數(shù)據(jù)結(jié)構(gòu)和過程作為兩個實體來對待,其著重點在過程。設(shè)計人員一方面考慮如何將功能分解,在每一個過程中又要著重安排程序的操作序列,但同時程序員在編程時又必須時時考慮數(shù)據(jù)結(jié)構(gòu),由于畢竟要將操作作用于數(shù)據(jù)上。數(shù)據(jù)結(jié)構(gòu)和過程的這種分離,給軟件人員導(dǎo)致沉重的承擔(dān)。例如,我們不也許規(guī)定數(shù)據(jù)結(jié)構(gòu)始終沒有變化,且不說在軟件維護(hù)的時候數(shù)據(jù)結(jié)構(gòu)有也許發(fā)生變化,就是在軟件開發(fā)的過程中也不能保證數(shù)據(jù)結(jié)構(gòu)不變化。面向過程的程序設(shè)計的缺陷之一就是一旦數(shù)據(jù)結(jié)構(gòu)需要變更的時候,必須修改與之有關(guān)的所有模塊。因此,面向過程的程序的可重用性差,維護(hù)代價高。下面,我們舉一個實例來進(jìn)一步討論面向過程的程序設(shè)計方法。考慮一個銀行系統(tǒng)。該系統(tǒng)允許顧客開設(shè)不同類型的銀行賬戶,其中涉及鈔票賬戶、支票賬戶和貸款賬戶,同時允許顧客存款、取款和轉(zhuǎn)賬。根據(jù)面向過程的程序設(shè)計方法,一方面我們將銀行系統(tǒng)分解成三個模塊分別負(fù)責(zé)存款、取款和轉(zhuǎn)賬三項工作。這三個過程是MakeDeposit、WithDraw和Transfer。接著,建立一個簡樸的數(shù)據(jù)結(jié)構(gòu):structaccount{charname;/*姓名*/unsignedlongaccountld;/*賬號*/floatbalance/*余額*/floatinterestYTD/*年利息*/characcountType./*賬戶類型(鈔票、支票和貸款)*/};然后,對每個過程按照一定的操作順序編寫程序。我們來分析一下,程序員所關(guān)心的是否與顧客一致。(1)對于一個顧客來說,他最關(guān)心的是賬戶中尚有多少錢,利息是多少,錢存在銀行是否安全,而不會對存錢和取錢的程序執(zhí)行的過程感愛好。對他而言,只是需要知道存、取款手續(xù),并按照這些手續(xù)去做就足夠了。(2)程序設(shè)計人員所關(guān)注的是如何寫存、取款的代碼,如何在已經(jīng)建立的數(shù)據(jù)結(jié)構(gòu)中填寫數(shù)據(jù)并管理它們??梢?程序員與顧客關(guān)心的事情是不一致的,這是由于數(shù)據(jù)結(jié)構(gòu)與“過程”的分離導(dǎo)致的。再進(jìn)一步分析,顧客與他們的銀行賬戶有沒有特殊的關(guān)系。在軟件系統(tǒng)中,由于顧客只但是是一串字符和數(shù)字,因而不用考慮到底是誰擁有該賬戶,賬戶里的內(nèi)容是什么,而銀行賬號也只但是是一個整數(shù)。此外,由于數(shù)據(jù)結(jié)構(gòu)與“過程”的分離,程序員可以非常方便地修改賬目,由于對他來說,只但是是在修改數(shù)據(jù)結(jié)構(gòu)中的數(shù)字,事實上他也許通過修改數(shù)據(jù)而取走顧客的錢。最后,我們考慮假如數(shù)據(jù)結(jié)構(gòu)發(fā)生了一些變化會產(chǎn)生什么樣的結(jié)果。對于accountType數(shù)據(jù)項,本來只有鈔票賬戶、支票賬戶和貸款賬戶三種取值,程序只能辨認(rèn)這三種取值。由于賬戶類型的不同,我們在編寫存款等過程時,將以不同的操作序列與之相應(yīng)(在同一個過程中分情況解決)。對鈔票賬戶、支票賬戶和貸款賬戶的解決不會完全相同。假設(shè)現(xiàn)在需要增長一種賬戶類型——退休賬戶,后果如何?本來的程序肯定犯錯。由于在本來的程序中我們只考慮了以上三種賬戶的情況,對于新增長的賬戶類型,本來的程序不會解決。也就是說,每增長一種新的賬戶類型,都必須重新編寫程序代碼,可見其維護(hù)軟件的開銷是相稱大的。上述這些問題的出現(xiàn)都是由于面向過程程序設(shè)計的解決方法的著重點在功能,而我們通過度析發(fā)現(xiàn),數(shù)據(jù)對于客戶(特別是顧客)似乎更重要。在這里,程序員關(guān)心的是如何做(howtodo),而顧客則關(guān)心的是做什么(whatt0do),這是由于過程和數(shù)據(jù)的分離導(dǎo)致的。使用面向?qū)ο蟮某绦蛟O(shè)計技術(shù)是解決這些問題的最佳方法。1.1.2面向?qū)ο蟪绦蛟O(shè)計的基本概念在面向?qū)ο蟮某绦蛟O(shè)計中,著重點在那些將要被操作的數(shù)據(jù),而不是在實現(xiàn)這些操作的過程。數(shù)據(jù)構(gòu)成了軟件分解的基礎(chǔ),而不是功能。我們一方面要分析顧客在賬戶(數(shù)據(jù))中要做什么,然后提供相應(yīng)的操作,更重要的是不能將數(shù)據(jù)和相應(yīng)操作當(dāng)作兩個分離的實體,而是要把它們作為一個完整的實體來對待。數(shù)據(jù)與定義在它上面的用戶需要的操作構(gòu)成一個整體。同時,數(shù)據(jù)自身不能被外部程序和過程直接存取。假如想修改銀行賬戶中的數(shù)據(jù),惟一的辦法是在該數(shù)據(jù)上提供修改操作,這些修改操作是以用戶應(yīng)得到的利益為根據(jù)。當(dāng)我們把對銀行賬戶的操作定義在數(shù)據(jù)上,銀行賬戶就是一個類,稱為銀行賬戶類。作為其實例,我們可以建立許多具體的銀行賬戶,而每一個具體的銀行賬戶就是銀行賬戶類的一個對象?,F(xiàn)在,我們給面向?qū)ο蟪绦蛟O(shè)計下一個定義。面向?qū)ο蟪绦蛟O(shè)計是一種新的程序設(shè)計范型。面向?qū)ο蟪绦虻闹匾Y(jié)構(gòu)特點是:第一,程序一般由類的定義和類的使用兩部分組成,在主程序中定義各對象并規(guī)定它們之間傳遞息的規(guī)律;第二,程序中的一切操作都是通過向?qū)ο蟀l(fā)送消息來實現(xiàn)的,對象接受到消息后,啟動有關(guān)方法完畢相應(yīng)的操作。面向?qū)ο蟪绦蛟O(shè)計的最大優(yōu)點就是軟件具有可重用性。當(dāng)人們對軟件系統(tǒng)的規(guī)定有所改變時,并不需要程序員做大量的工作,就能使系統(tǒng)做相應(yīng)的變化。類與對象是面向?qū)ο蟪绦蛟O(shè)計中最重要的概念,也是一個難點,想要掌握面向?qū)ο蟪绦蛟O(shè)計的技術(shù),一方面就要很好地理解這兩個概念。1.2對象與類1.2.1對象與類的概念在現(xiàn)實世界中,人們是如何結(jié)識“對象”和“類”的。在平常生活中對象就是我們結(jié)識世界的基本單元,它可以是人,也可以是物,還可以是一件事。整個世界就是由形形色色的“對象”構(gòu)成的。例如一輛車、一個球、一個小學(xué)生、一次表演。對象既可以很簡樸,也可以很復(fù)雜,復(fù)雜的對象可以由若干簡樸的對象構(gòu)成。對象是現(xiàn)實世界中的一個實體,其特性是:(1)每一個對象必須有一個名字以區(qū)別于其它對象;(2)用屬性(或叫狀態(tài))來描述它的某些特性;(3)有一組操作,每一個操作決定對象的一種行為。在平常生活中,“類”是對一組具有共同的屬性特性和行為特性的對象的抽象。例如,由一個個的人構(gòu)成人類,而一個人是人類的一個實例。類和對象之間的關(guān)系是抽象和具體的關(guān)系。類是對多個對象進(jìn)行綜合抽象的結(jié)果,對象又是類的個體實物,一個對象是類的一個實例。例如,教師黎明和學(xué)生李明都是一個對象。對象名:黎明對象名:李明對象的屬性:對象的屬性:年齡:30年齡:20學(xué)歷:博士學(xué)歷:本科職稱:專家性別:男專業(yè):計算機(jī)軟件專業(yè):計算機(jī)科學(xué)與技術(shù)對象的操作:對象的操作:說自己的年齡打籃球吃飯睡覺授課聽課一個個的像黎明這樣的教師就構(gòu)成教師類。一個個的像李明這樣的學(xué)生就構(gòu)成學(xué)生類。我們前面說過,面向?qū)ο蟪绦蛟O(shè)計更接近人們的思維。面向?qū)ο蟪绦蛟O(shè)計中的對象和就來源于現(xiàn)實世界。以面向?qū)ο蟪绦蛟O(shè)計的觀點看,一個對象是由描述其屬性的數(shù)據(jù)和定義在其上面的一組操作組成的實體,是數(shù)據(jù)單元和過程單元的組合體。類是對一組對象的抽象,這組對象具有相同的屬性結(jié)構(gòu)和操作行為,在對象所屬的類中要說明這些結(jié)構(gòu)和行為。一個對象是類的一個實例。有了類,才可以創(chuàng)建對象?,F(xiàn)在我們給出類的更精確的定義:類是創(chuàng)建對象的樣板,它包含對創(chuàng)建對象的狀態(tài)描述和對操作行為的說明。假如用面向?qū)ο蟮挠^點來分析銀行賬戶問題,著重點在銀行賬戶上,而不是在存款和取款的行為上,那么,銀行賬戶就是一個類。classBankAccount{public:voidMakeDeposit(float(yī)amount);floatWithDraw(floatamount);boolTransfer(BankAccount&to,floatamount);private:floatbalance;floatinterestYTD;char*owner;intaccount_number;);在BankAccount類中,說明的行為是MakeDeposit、WithDraw和Transfer。這些行為對于任何客戶來說是很重要的,他們在銀行開戶的目的就是要進(jìn)行存款、取款以及轉(zhuǎn)賬。正由于每一個顧客(作為類的實例)都也許做這些操作,所以對行為的說明是public,即公有的。同時,在BankAecount類中,還說明了數(shù)據(jù)balance、interestYTD、owner和account—number,這些數(shù)據(jù)是私有的,只能在被定義的類中進(jìn)行操作。作為銀行賬戶類的實例,銀行的每一個銀行賬戶都是一個對象。每個銀行賬戶對象有相同的結(jié)構(gòu)和行為。因此,任何一個銀行賬戶對象都可以使用在類中說明的MakeDeposit等操作,并且每個銀行賬戶對象有相同類型的數(shù)據(jù)結(jié)構(gòu)balance等。在面向?qū)ο蟪绦蛟O(shè)計中,一個類只在源程序的代碼中出現(xiàn),而并不會在一個正在內(nèi)存運營的程序中出現(xiàn),即類只是在編譯時存在;對象作為類的實例在運營的程序中出現(xiàn),并占有內(nèi)存空間,它是在運營時存在的實體。所以一個類事實上是一種新的數(shù)據(jù)類型,當(dāng)我們要用一個新的數(shù)據(jù)類型時,一方面要在源程序中說明,而說明部分的代碼是不在內(nèi)存中運營的。在程序中運營的是該類的對象,對象在內(nèi)存完畢。注意,我們在此必須嚴(yán)格區(qū)分說明和定義。前面我們用C++寫的程序段是對類BankAccount的說明。在c++的類中,我們把那些行為稱為成員函數(shù),而把數(shù)據(jù)稱為數(shù)據(jù)成員。1.2.2對象的狀態(tài)在面向?qū)ο蟪绦蛟O(shè)計中,對象是類的實例。對象給類以生命,類想要做的事必須通過建立對象和在對象上進(jìn)行操作而實現(xiàn)。創(chuàng)建類的對象的過程也叫實例化對象。對象知道什么能做和什么不能做,并且有能力修改和維護(hù)定義在對象上的數(shù)據(jù)??梢詫ο螽?dāng)作是一個帶有狀態(tài)和行為的活的實體。屬于同一個類中的對象具有相同的行為,但是有各自獨立的狀態(tài)。什么是對象的狀態(tài)?在現(xiàn)實世界中一個對象能獨立存在的因素是它們有各自的特性,這些特性就是對象的狀態(tài)。對于一個人來說,姓名、性別、身高都是其狀態(tài)。在前面的討論中,對象的屬性與對象的狀態(tài)是相同的概念。這里,給對象的狀態(tài)下一個定義:對象的狀態(tài)是所有靜態(tài)屬性和這些屬性的動態(tài)值的總和。,以銀行賬戶為例,BankAccount類對象有一項數(shù)據(jù)成員balance(余額)。假設(shè)銀行不允許透支,那么每個賬戶的余額(balance)不應(yīng)小于零。這是所有銀行賬戶類對象的公共屬性,也可以說是任何一個銀行賬戶類對象的靜態(tài)屬性。這類屬性是不需要檢測的。然而,在BankAccount類對象的生存期的任何時刻,賬戶中的余額是包含在balance這個數(shù)據(jù)成員中的數(shù)值。當(dāng)在對象上發(fā)生存款、轉(zhuǎn)賬、取款等行為時,會引起該數(shù)值的變化。因此,賬戶余額是一個動態(tài)變化的值,換句話說,數(shù)據(jù)成員balance的值是動態(tài)的。對象的狀態(tài)通常不僅僅是初等的數(shù)據(jù)類型(整型、實型、字符型等),并且許多對象將另一個對象作為它們狀態(tài)的一部分。例如,一輛車有發(fā)動機(jī)、車輪、座位,發(fā)動機(jī)是此外一個對象,它可以作為車的狀態(tài)的一部分,。又例如,一個銀行對象可以將銀行賬戶對象和顧客對象作為它的狀態(tài)的一部分。一輛車一個學(xué)校發(fā)動機(jī)發(fā)動機(jī)座位為位座位座位車輪車輪車輪學(xué)生學(xué)生教師教師1.2.3對象的交互現(xiàn)實世界中的對象不是孤立存在的實體,他們之間存在著各種各樣的聯(lián)系,正是它們之間的互相作用、聯(lián)系和連接,才構(gòu)成了世間各種不同的系統(tǒng)。同樣,在面向?qū)ο蟪绦蛟O(shè)計中,對象之間也需要聯(lián)系,我們稱為對象的交互。面向?qū)ο蟪绦蛟O(shè)計技術(shù)必須提供一種機(jī)制,允許一個對象與另一個對象的交互。這種機(jī)制叫消息傳遞。在面向?qū)ο蟪绦蛟O(shè)計中的消息傳遞,實際是對現(xiàn)實世界中的信息傳遞的直接模擬。一個對象向另一個對象發(fā)出的請求被稱為“消息”。消息是一個對象規(guī)定另一個對象執(zhí)行某個功能操作的規(guī)格的說明,通過消息傳遞才干完畢對象之間的互相請求或互相協(xié)作。例如,我們有一個銀行賬戶對象和一個顧客對象,顧客對象可以請求銀行賬戶對象的服務(wù),如“存入300元”、“取出200元”等,當(dāng)銀行賬戶對象接到請求后,擬定應(yīng)執(zhí)行的相應(yīng)的操作并執(zhí)行。在此,我們有必要介紹一下方法的概念。方法是面向?qū)ο蟪绦蛟O(shè)計中的一個術(shù)語。我們知道,屬于一個類的對象具有相同的行為,當(dāng)某個行為作用在對象時,我們就稱對象執(zhí)行了一個方法。方法定義了一系列的計算環(huán)節(jié)。所以,我們可以說一個對象請求另一個對象執(zhí)行一個特定的方法,或者說一個對象發(fā)送一個消息給另一個對象,引起那個對象方法的執(zhí)行。從這個意義上看,對象的行為是負(fù)責(zé)響應(yīng)消息并進(jìn)行操作。一般情況下,我們稱發(fā)送消息的對象為發(fā)送者或請求者,接受消息的對象為接受者或目的對象。對象中的聯(lián)系只能通過消息傳遞來進(jìn)行。接受者只有在接受到消息時,才干被激活,被激活的對象會根據(jù)消息的規(guī)定完畢相應(yīng)的功能。消息具有三個性質(zhì):(1)同一個對象可以接受不同形式的多個消息,做出不同的響應(yīng);(2)相同形式的消息可以傳遞給不同的對象,所做出的響應(yīng)可以是不同的;(3)消息的發(fā)送可以不考慮具體的接受者,對象可以響應(yīng)消息,也可以不響應(yīng)。事實上,對象之間的消息傳遞機(jī)制相應(yīng)于面向過程程序設(shè)計的過程調(diào)用。消息傳遞并非真的傳遞信息,它的實質(zhì)就是方法的調(diào)用。只但是方法的調(diào)用受到消息的控制,而過程調(diào)用是直接的。消息的內(nèi)容一般應(yīng)涉及接受者的名字、請求的方法、一個或多個參數(shù)。由發(fā)送者向接受者發(fā)送一條消息,就是規(guī)定調(diào)用特定的方法。所調(diào)用的方法也許引起對象狀態(tài)的改變,還也許會生成更多的消息,而導(dǎo)致調(diào)用其它對象中的方法。在面向?qū)ο蟪绦蛟O(shè)計中,消息分為兩類:公有消息和私有消息。假設(shè)有一批消息同屬于一個對象,其中一部分消息是由其它對象直接向它發(fā)送的,稱為公有消息;另一部分消息是它向自己發(fā)送的,稱為私有消息。公有消息與私有消息的擬定,與消息規(guī)定調(diào)用的方法有關(guān)。假如被調(diào)用的方法在對象所屬的類中是在public下說明的,則為公有;是在private下說明的,即為私有。當(dāng)然,私有消息只能發(fā)送調(diào)用屬于它自己的方法。例如,一個銀行賬戶對象的類定義是BankAccount,一個顧客對象可以發(fā)送一個公有消息WithDraw給銀行賬戶對象,規(guī)定取款。這個消息是公有消息。1.2.4類的擬定與劃分我們知道,面向?qū)ο蟪绦蛟O(shè)計技術(shù)是將系統(tǒng)分解成若干對象,對象之間的互相作用構(gòu)成了整個系統(tǒng)。而類是創(chuàng)建對象的樣板,在整體上代表一組對象,設(shè)計類而不是設(shè)計對象可以避免反復(fù)的編碼工作,類只需編碼一次,就可以創(chuàng)建所有的對象。所以,當(dāng)我們輯決實際問題時,需要對的地進(jìn)行分“類”。我們必須理解一個類究竟表達(dá)的是哪一組對象,如何把實際問題中的事物匯聚成一個個的“類”,而不是一組數(shù)據(jù)。這是面向?qū)ο蟪绦蛟O(shè)計中的一個難點。例如,考慮銀行系統(tǒng),我們至少應(yīng)當(dāng)有兩類對象:顧客類和銀行賬戶類。學(xué)校系統(tǒng)應(yīng)至少包含兩類對象:學(xué)生和教師。如何擬定和劃分類?類的擬定和劃分并沒有統(tǒng)一的標(biāo)準(zhǔn)和固定的方法,基本上依賴設(shè)計人員的經(jīng)驗、技巧以及對實際問題的把握。一個基本的原則是:尋求一個大系統(tǒng)中事物的共性,將具有共性的系統(tǒng)成分?jǐn)M定為一個類。這里以模擬一個學(xué)校系統(tǒng)為例。系統(tǒng)想要達(dá)成的目的不同,擬定和劃分的類就不相同。若模擬的目的是為了管理教學(xué),設(shè)立的類也許是學(xué)生、教師、教材、課程、教室、圖書等。若模擬的目的是管理后勤工作,設(shè)立的類也許是宿舍、食堂、后勤工作人員、教室、圖書館等。擬定一個事物是一個類的第一步,是要判斷它是否有一個以上的實例,假如有,則它也許是一個類;第二步,我們還要判斷類的實例中有否絕對的不同點,假如沒有,則它是一個類。由于類的每一個實例是相似的,具有相同的行為和屬性結(jié)構(gòu)。例如,顏色(Color)與鮮花聯(lián)系在一起只是鮮花的一種狀態(tài),由于表達(dá)顏色的是一些值:紅、黃、紫、白等,所以,在此Color不是一個類。然而,假如我們把顏色同涉及復(fù)雜顏色計算的圖形解決系統(tǒng)聯(lián)系在一起,則Color是一個類,由于這時的顏色是基于顏色三元素(紅、綠、藍(lán))的成分比例和色度的變量,它不僅僅是一個數(shù)值,還可以附帶很多的行為。不能把一組函數(shù)組合在一起構(gòu)成類。也就是說,不能把一個面向過程的模塊直接變成類。假如簡樸地將模塊中的函數(shù)變成成員函數(shù)而使其成為類是錯誤的。類不是函數(shù)的集合。例如,考慮一個包含一組數(shù)學(xué)函數(shù)的模塊,現(xiàn)在我們定義一個類Mathhelper:classMathelper{public:doublesqrt(doubleaNumber),doublePower(doubleaNumber,intraiseto)‘doubleInverse(doubleaNumber);privat(yī)e://任何數(shù)據(jù)項,也也許沒有};擬定Mathelper為一個類是錯誤的。問題在于該類中沒有需要管理的私有數(shù)據(jù)。用戶只需要提供參數(shù)對成員函數(shù)進(jìn)行調(diào)用。這與面向過程的程序設(shè)計的函數(shù)調(diào)用沒有主線的區(qū)別。設(shè)計類要有一個明確的目的。一個好的類應(yīng)當(dāng)是容易理解和使用的。我們不能設(shè)計一個Color類來表達(dá)鮮花的顏色,但是可以在圖形解決系統(tǒng)中將顏色Color設(shè)計為類。由于在兩個系統(tǒng)中對顏色的規(guī)定不同。1.3數(shù)據(jù)的抽象與封裝面向?qū)ο笙到y(tǒng)中最突出的特性是封裝性、繼承性和多態(tài)性。我們一方面來討論封裝性,封裝與數(shù)據(jù)抽象的概念密切相關(guān)。1.3.1現(xiàn)實世界中的抽象與封裝抽象和封裝的概念在現(xiàn)實世界中廣泛存在,特別在科學(xué)技術(shù)日益發(fā)展的今天,大量的電器被人們使用,對電器的使用體現(xiàn)了抽象與封裝的概念。以錄音機(jī)為例,錄音機(jī)上有若干按鍵,當(dāng)人們使用錄音機(jī)時,只要根據(jù)自己的需要,如放音、錄音、停止、倒帶等,按下與之相應(yīng)的鍵,錄音機(jī)就會完畢相應(yīng)的工作。這些按鍵安裝在錄音機(jī)的表面,人們通過它們與錄音機(jī)交互。我們無法(當(dāng)然也沒必要)操作錄音機(jī)的內(nèi)部電路,由于它們被裝在機(jī)殼里,錄音機(jī)的內(nèi)部情況對于用戶來說是隱蔽的,不可見的。這就是所謂封裝的原理。那么,我們是如何知道放音按哪個鍵,停止又按哪個鍵的呢?是錄音機(jī)的操作說明書告訴我們的,但操作說明書并不告訴我們錄音機(jī)的內(nèi)部將如何去做這些事。操作說明書在錄音機(jī)做什么(whattddo)與如何做(howtodo)之間做出了明確的區(qū)分。這就是所謂抽象的原理。抽象出來的是做什么,而不關(guān)心如何實現(xiàn)這些操作。以一般觀點而言,抽象是通過特定的實例或例子抽取共同性質(zhì)以后形成概念的過程。抽象是對系統(tǒng)的簡化描述或規(guī)范說明,它強(qiáng)調(diào)了系統(tǒng)中的一部分細(xì)節(jié)和特性,例如做什么,而忽略了其它部分,例如如何做。抽象的描述被稱為它的規(guī)范說明,例如錄音機(jī)的操作說明書,而對抽象的解釋稱為它的實現(xiàn)。1.3.2數(shù)據(jù)的抽象與封裝的基本概念將上述觀點用在數(shù)據(jù)結(jié)構(gòu)上,就不難理解數(shù)據(jù)的抽象與封裝。將數(shù)據(jù)結(jié)構(gòu)和作用于數(shù)據(jù)結(jié)構(gòu)上的操作組成一個實體,數(shù)據(jù)的表達(dá)方式和對數(shù)據(jù)的操作細(xì)節(jié)被隱藏起來,用戶通過操作接口對數(shù)據(jù)進(jìn)行操作。對于用戶來說,只知道如何通過操作接口對該數(shù)據(jù)進(jìn)行操作,而并不知道是如何做的也不知道數(shù)據(jù)是如何表達(dá)的。這就是數(shù)據(jù)的封裝。數(shù)據(jù)的抽象則是通過對數(shù)據(jù)實例的分析,抽取其共同性質(zhì)的結(jié)果。數(shù)據(jù)的抽象和我們前面討論的類的概念之間顯然存在著很強(qiáng)的相似性。在面向?qū)ο蟪绦蛟O(shè)計中,數(shù)據(jù)的抽象是在擬定類時強(qiáng)調(diào)對象的共同點而忽略它們的不同點的結(jié)果。也可以說,在一個類的說明中我們只表達(dá)那些重要特性,而忽略次要的、引不起我們愛好的東西。數(shù)據(jù)的封裝則是隱藏了抽象的內(nèi)部實現(xiàn)細(xì)節(jié)的結(jié)果。封裝是將數(shù)據(jù)抽象的外部接口與內(nèi)部的實現(xiàn)細(xì)節(jié)清楚地分離開。抽象和封裝是互補(bǔ)的。好的抽象有助于封裝,封裝的實體則幫助維護(hù)抽象的完整性。重要的是抽象先于封裝。以銀行賬戶類為例,balance、interestYTD、owner、account—number等私有數(shù)據(jù)是被封裝的數(shù)據(jù),MakeDeposit、WithDraw、Transfer等成員函數(shù)的細(xì)節(jié)也同時被封裝,用戶看到的是MakeDeposit、WithDraw、Transfer操作提供的接口。接口實現(xiàn)細(xì)節(jié)(不可見)MakeDepositMakeDepositWithDrawTransferBalanceInterestYTDOwneraccount—numberMakeDepositWithDrawTransfer用戶不能存取的數(shù)據(jù)在上面的討論中,我們并沒有嚴(yán)格區(qū)分銀行賬戶是類還是對象,由于封裝性不僅涉及到類的描述,也涉及到組成軟件系統(tǒng)的對象。從類的實例——對象——的角度來討論封裝似乎更合理,由于類并不真正占有存儲空間。封裝的單位實際是對象,但是對象的結(jié)構(gòu)和行為是用它自己的類說明來描述的。對象的封裝比類的封裝更具體化。可以從下面幾點來理解對象的封裝:(1)對象具有一個清楚的邊界,對象的私有數(shù)據(jù)、成員函數(shù)的細(xì)節(jié)被封裝在該邊界內(nèi);(2)具有一個描述對象與其它對象如何互相作用的接口,該接口必須說明消息傳遞的使用方法;,(3)對象內(nèi)部的代碼和數(shù)據(jù)應(yīng)受到保護(hù),其它對象不能直接修改。從用戶(或應(yīng)用程序員)的觀點看,對象提供了一組服務(wù),并提供了請求服務(wù)的接口。從系統(tǒng)設(shè)計員的角度看,封裝能清楚地標(biāo)明對象提供的服務(wù)界面,而水鄉(xiāng)的行為和數(shù)據(jù)是隱蔽的,不可見。對象的這一封裝機(jī)制,可以將對象的使用者和設(shè)計者分開。1.3.3對象的特性封裝性。模塊的獨立性。動態(tài)連接性。易維護(hù)性1.4繼承性1.4.1繼承的概念孩子的父母孩子的父母孩子哺乳動物熱血、有毛發(fā)、用奶哺育幼子狗有犬牙、食肉、特定的骨骼結(jié)構(gòu)、群居柯利狗尖鼻子、身體顏色紅白相間、適合放牧上圖說明了哺乳動物、狗、柯利狗之間的繼承關(guān)系。圖中箭頭方向志向基對象。哺乳動物是一種熱血、有毛發(fā)、用奶哺育幼仔的動物;狗是有犬牙、食肉、特定的骨骼結(jié)構(gòu)、群居的哺乳動物;柯利狗是尖鼻子、身體顏色紅白相聞、適合放牧的狗。在繼承鏈中,每個類繼承了它前一個類的所有特性。例如,狗具有哺乳動物的所有特性,同時還具有區(qū)別于其它哺乳動物(如貓、大象等)的特性。圖中從下到上的繼承關(guān)系是:柯利狗是狗,狗是哺乳動物?!翱吕贰鳖惱^承了“狗”類的特性,“狗”類繼承了“哺乳動物”類的特性。以面向?qū)ο蟪绦蛟O(shè)計的觀點來看,繼承所表達(dá)的是對象類之間相關(guān)的關(guān)系。這種關(guān)系使得某類對象可以繼承此外一類對象的特性和能力。若類之間具有繼承關(guān)系.則它們之間具有下列幾個特性:(1)類間具有共享特性(涉及數(shù)據(jù)和程序代碼的共享);(2)類間具有差別或新增部分(涉及非共享的數(shù)據(jù)和程序代碼);(3)類間具有層次結(jié)構(gòu)。假設(shè)有兩個類A和B,若類B繼承類A,則屬于類B中的對象具有類A的一切特性(涉及數(shù)據(jù)屬性和操作),這時,我們稱被繼承類A為基類或父類或超類;而稱繼承類B為類A的派生類或子類。同時,我們還可以說,類B是從類A中派生出來的。假如類B從類A派生出來,而類C又是從類B派生出來的,就構(gòu)成了類的層次。這樣,我們又有了直接基類和間接基類的概念。類A是類B的直接基類,是類c的間接基類。類c不僅繼承它的直接基類的所有特性,還繼承它的所有間接基類的特性。對于動物繼承鏈,用面向?qū)ο蟪绦蛟O(shè)計的術(shù)語,我們稱“哺乳動物”是“狗”的基類,“狗”是“哺乳動物”的派生類?!安溉閯游铩?、“狗”、“柯利狗”構(gòu)成類的層次?!安溉閯游铩笔恰肮贰钡闹苯踊?是“柯利狗”的間接基類。假如類B是類A的派生類,那么,在構(gòu)造類B的時候,我們不必重新描述A的所有特性,我們只需讓它繼承類A的特性,然后描述與基類A不同的那些特性。也就是說,類B的特性由繼承來的和新添加的兩部分特性構(gòu)成。具體地說,繼承機(jī)制允許派生類繼承基類的數(shù)據(jù)和操作(即數(shù)據(jù)成員和成員函數(shù)),也就是說,允許派生類使用基類的數(shù)據(jù)和操作。同時,派生類還可以增長新的操作和數(shù)據(jù)。例如,子女類可以從父母類繼承房子和汽車,當(dāng)然可以使用房子和汽車,還可以對房子進(jìn)行再裝修。繼承的作用有兩個:其一,避免公用代碼的反復(fù)開發(fā),減少代碼和數(shù)據(jù)冗余;其二,通過增強(qiáng)一致性來減少模塊間的接口和界面。繼承使程序不再是毫無關(guān)系的類的堆砌,而具有良好的結(jié)構(gòu)。繼承機(jī)制為程序員們提供了一種組織、構(gòu)造和重用類的手段。繼承使一個類(基類)的數(shù)據(jù)結(jié)構(gòu)和操作被另一個類(派生類)重用,在派生類中只需描述其基類中沒有的數(shù)據(jù)和操作。這樣,就避免了公用代碼的反復(fù)開發(fā),增長了程序的可重用性,減少了代碼和數(shù)據(jù)冗余。同時,在描述派生類時,程序員還可以覆蓋基類的一些操作,或修改和重定義基類中的操作,例如子女對所繼承的房子進(jìn)行裝修。繼承機(jī)制以相關(guān)的關(guān)系來組織事物,可以減少我們對相似事物進(jìn)行說明和記憶的規(guī)模,為我們提供了一種簡化的手段。程序員可以將相關(guān)的類收集在一起,生成高一級的、概括了這些類的共性的類。具有適應(yīng)關(guān)系的類處在一個繼承層次結(jié)構(gòu)中,高層的類作為低層的類的抽象,使程序員可以忽略那些低層類的不同實現(xiàn)細(xì)節(jié),而按照高層類編寫通用程序,并且在掌握了高層類的特性以后,可以不久地掌握低層類的特性,給編程工作帶來方便。1.4.2繼承的分類繼承有兩種分類方法,一種是從繼承源上分,另一種是從繼承內(nèi)容上分。從繼承源上分,繼承分為單繼承和多繼承。單繼承是指每個派生類只直接繼承了一個基類的特性。前面介紹的動物鏈,就是一個單繼承的實例。圖1.5也表達(dá)了一種單繼承關(guān)系,即Windows操作系統(tǒng)的窗口之間的繼承關(guān)系。單繼承并不能解決繼承中的所有問題,例如,小孩喜歡的玩具車既繼承了車的一些特性,又繼承了玩具的一些特性,如圖1.6所示。此時“玩具車”類不是繼承了一個基類的特性,而是繼承了“玩具”和“車”兩個基類的特性,這是一種多繼承的關(guān)系。多繼承是指多個基類派生出一個派生類的繼承關(guān)系,多繼承的派生類直接繼承了不止一個基類的特性。從繼承內(nèi)容上劃分,繼承可分為取代繼承、包含繼承、受限繼承、特化繼承。取代繼承:例如徒弟從師傅那里學(xué)到的所有技術(shù),在任何需要師傅的地方都可以由徒弟來替代,這就屬于取代繼承?!^承:例如“柯利狗”繼承了“狗”的所有特性,任何一條“柯利狗”都是一條“狗”,這就屬于包含繼承。受限繼承:例如“鴕鳥”盡管繼承了“鳥”的一些特性,但不能繼承鳥會飛的特性,這就屬于受限繼承。特化繼承:例如“運動員”是一類特殊的人,比一般人具有更多體育專長,這就屬于特化繼承。1.4.3繼承與封裝的關(guān)系在面向?qū)ο蟪绦蛟O(shè)計中,對象具有封裝性,對象之間的聯(lián)系只能通過消息傳遞來完畢,對象的私有數(shù)據(jù)和行為是被隱藏起來的。那么,繼承機(jī)制的引入是否削弱了封裝性?繼承與封裝是否產(chǎn)生矛盾?回答是否認(rèn)的。繼承與封裝不僅投有實質(zhì)性的沖突,并且尚有一定的相似性。在面向?qū)ο笙到y(tǒng)中,封裝的單位是對象,也就是說,把一個屬于某一類的對象封裝起來,使其數(shù)據(jù)和操作成為一個整體。假如該對象所屬的類是一個派生類,那么,它只要把從基類那里繼承來的操作和數(shù)據(jù)與自己的操作和數(shù)據(jù)一并封裝起來,就可以了。對象仍然是封裝好的整體,仍然只通過消息傳遞與其它的對象交互,而不是直接調(diào)用。所以,一個對象,無論它是基類的實例,還是派生類的實例,都是一個被封裝的實體。因此,我們得出結(jié)論:繼承機(jī)制的引入并不影響對象的封裝性。從另一角度看,繼承與封裝尚有相似性,那就是它們都提供了共享代碼的手段,因而增長了代碼的重用性。繼承提供的代碼共享是靜態(tài)的,派生類對象在成為活動的實體以后,自動地共享其基類中定義的代碼段,從而使基類對象與其派生類對象共享一段代碼。封裝提供的代碼共享是動態(tài)的,例如我們在一個類中說明了一段代碼,那么屬于該類的多個實例在程序運營時共享在類中說明的那段代碼。1.5多態(tài)性1.5.1什么是多態(tài)性多態(tài)性也是面向?qū)ο笙到y(tǒng)的重要特性。在討論面向?qū)ο蟪绦蛟O(shè)計的多態(tài)性之前,我們還是來看看現(xiàn)實世界的多態(tài)性?,F(xiàn)實世界的多態(tài)性在自然語言中經(jīng)常出現(xiàn)。假設(shè)一輛汽車停在了屬于別人的車位,司機(jī)也許會聽到這樣的規(guī)定:“請把你的車挪開”,司機(jī)在聽到請求后,所做的工作應(yīng)當(dāng)是把車開走。在家里,一把凳子擋住了孩子的去路,他也許會請求媽媽:“請把凳子挪開”,媽媽過去搬起凳子,放在一邊。在這兩件事情中,司機(jī)和媽媽的工作都是“挪開”同樣?xùn)|西,但是他們在聽到請求以后的行為是截然不同的,這就是多態(tài)性。對于“挪開”這個請求,還可以有更多的行為與之相應(yīng)?!芭查_”從字面上看是相同的,但由于用的對象不同,操作的方法就不同。面向?qū)ο蟪绦蛟O(shè)計借鑒了現(xiàn)實世界的多態(tài)性。面向?qū)ο笙到y(tǒng)的多態(tài)性是指不同的對象收到相同的的消息時產(chǎn)生多種不同的行為方式。例如,我們有一個窗口(Window)類對象,還一個棋子(ChessPiece)類對象,現(xiàn)在我們來考慮對它們都發(fā)出“移動”的消息,“移動”操作在Window類對象和ChessPiece類對象上可以有不同的行為。c++語言支持兩種多態(tài)性,即編譯時的多態(tài)性和運營時的多態(tài)性。編譯時的多態(tài)性是通過重載來實現(xiàn)的,我們將在1.5.2介紹其概念。運營時的多態(tài)性是通過虛函數(shù)來實現(xiàn)的,程序運營的到底是哪個函數(shù)版本,需要在運營時通過對象發(fā)送的消息來擬定。由于虛函數(shù)的概念略為復(fù)雜,并且涉及到c++的語法細(xì)節(jié),在此不做進(jìn)一步的討論。1.5.2重載的概念重載一般涉及函數(shù)重載和運算符重載。函數(shù)重載是指一個標(biāo)記符可同時用于為多個函數(shù)命名,而運算符重載是指一個運算符可同時用于多種運算。也就是說,相同名字的函數(shù)或運算符在不同的場合可以表現(xiàn)出不同的行為。下面我們給出一個函數(shù)重載的例子。classA{public:voidPrint(inti){語句段1;}voidPrint(floatf){語句段2;}voidPrint(constchar*c)(語句段3;}//其它語句};在上面的類定義中我們重載了三個函數(shù),名字都是Print。它們有各自不同的功能,分別用語旬段1、語句段2、語句段3中的語句實現(xiàn),在此略去語句的細(xì)節(jié)。函數(shù)名相同,而函數(shù)實現(xiàn)的功能不同。那么,當(dāng)有規(guī)定使用Print函數(shù)的消息發(fā)送時,到底應(yīng)當(dāng)執(zhí)行函數(shù)的哪一個呢?這就要看消息傳遞的函數(shù)參數(shù)是什么,根據(jù)參數(shù)來調(diào)用不同的同名函數(shù)。例如,發(fā)送的消息是Print(20),則執(zhí)行的是語句段1,而發(fā)送的消息是Print(”welcome”),則執(zhí)行的是語句段3。為什么要使用重載?使用重載的目的是為了更好地表達(dá)行為共享,這種行為共享就像將相似的操作劃分在一
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 度農(nóng)業(yè)供應(yīng)鏈合同:農(nóng)副產(chǎn)品
- 度工程借款合同范本
- 設(shè)計公司內(nèi)部培訓(xùn)合同樣本
- 標(biāo)準(zhǔn)勞動合同模板合同
- 委托代理合同(公民類)范本
- 飾品定制合同范本
- 短期租賃合同格式
- 地下車庫車位承包合同轉(zhuǎn)讓協(xié)議
- 設(shè)備定期保養(yǎng)合同范文
- 大學(xué)生創(chuàng)新創(chuàng)業(yè)項目合同
- 大學(xué)普通物理-習(xí)題答案(程守洙-江之勇主編-第六版)課件
- 2023年山東藥品食品職業(yè)學(xué)院單招綜合素質(zhì)考試筆試題庫及答案解析
- 《工程化學(xué)》全套教學(xué)課件
- 4.1比的意義 導(dǎo)學(xué)案 2022-2023學(xué)年六年級數(shù)學(xué)上冊-人教版(含答案)
- 美容手術(shù)的麻醉精品課件
- 蔬菜生產(chǎn)技術(shù)實踐教學(xué)大綱
- 施耐德APC1-20K不間斷電源內(nèi)部培訓(xùn)(ppt可編輯修改)課件
- 看圖寫話我是乖孩子
- 油管、套管等規(guī)格對照表
- IEST-RP-CC0053
- 模糊邏輯與模糊推理
評論
0/150
提交評論