版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
第八章類和對象計算機基礎教學研究室C++語言程序設計1主要內容8.1面向對象程序設計方法概述8.2類的聲明和對象的定義8.3類的成員函數8.4對象成員的引用8.5類的封裝性和信息隱蔽8.6類和對象的簡單應用舉例2 到目前為止,我們介紹的是C++在面向過程的程序設計中的應用。對于規(guī)模比較小的程序,編程者可以直接編寫出一個面向過程的程序,詳細地描述每一瞬時的數據結構及對其的操作過程。但是當程序規(guī)模較大時,就顯得力不從心了。C++就是為了解決編寫大程序過程中的困難而產生的。8.1面向對象程序設計方法概述31.對象客觀世界中任何一個事物都可以看成一個對象(object)。對象可大可小。對象是構成系統(tǒng)的基本單位。一個對象往往是由一組屬性和一組行為構成的。一般來說,凡是具備屬性和行為這兩種要素的,都可以作為對象。2.封裝與信息隱蔽面向對象程序設計方法的一個重要特點就是“封裝性”(encapsulation),所謂“封裝”,指兩方面的含義:一、將有關的數據和操作代碼封裝在一個對象中,形成一個基本單位,各個對象之間相對獨立,互不干擾。二、將對象中某些部分對外隱蔽,即隱蔽其內部細節(jié),只留下少量接口,以便與外界聯系,接收外界的消息。信息隱蔽還有利于數據安全,防止無關的人了解和修改數據。面向對象程序設計中的概念43.抽象 在程序設計方法中,常用到抽象(abstraction)這一名詞。抽象的過程是將有關事物的共性歸納、集中的過程。 抽象的作用是表示同一類事物的本質。C++中的類就是對一批具體的數的抽象。 類是對象的抽象,而對象則是類的特例,或者說是類的具體表現形式。4.繼承與重用 如果在軟件開發(fā)中已經建立了一個名為A的“類”,又想另外建立一個名為B的“類”,而后者與前者內容基本相同,只是在前者的基礎上增加一些屬性和行為,只需在類A的基礎上增加一些新內容即可。這就是面向對象程序設計中的繼承機制。利用繼承可以簡化程序設計的步驟。
C++提供了繼承機制,采用繼承的方法可以很方便地利用一個已有的類建立一個新的類。這就是常說的“軟件重用”的思想。55.多態(tài)性 如果有幾個相似而不完全相同的對象,有時人們要求在向它們發(fā)出同一個消息時,它們的反應各不相同,分別執(zhí)行不同的操作。這種情況就是多態(tài)現象。 如,在Windows環(huán)境下,用鼠標雙擊一個文件對象(這就是向對象傳送一個消息),如果對象是一個可執(zhí)行文件,則會執(zhí)行此程序,如果對象是一個文本文件,則啟動文本編輯器并打開該文件。 在C++中,所謂多態(tài)性(polymorphism)是指:由繼承而產生的相關的不同的類,其對象對同一消息會作出不同的響應。 多態(tài)性是面向對象程序設計的一個重要特征,能增加程序的靈活性。6傳統(tǒng)的面向過程程序設計是圍繞功能進行的,用一個函數實現一個功能。所有的數據都是公用的,一個函數可以使用任何一組數據,而一組數據又能被多個函數所使用(見圖8.3)。圖8.38.1.2面向對象程序設計的特點7面向對象程序設計采取的是另外一種思路。程序設計者的任務包括兩個方面:一是設計所需的各種類和對象,即決定把哪些數據和操作封裝在一起;二是考慮怎樣向有關對象發(fā)送消息,以完成所需的任務。這時它如同一個總調度,不斷地向各個對象發(fā)出命令,讓這些對象活動起來(或者說激活這些對象),完成自己職責范圍內的工作。各個對象的操作完成了,整體任務也就完成了。顯然,對一個大型任務來說,面向對象程序設計方法是十分有效的,它利用代碼的重用,大大降低程序設計人員的工作難度,減少出錯機會。8類是C++中十分重要的概念,它是實現面向對象程序設計的基礎。類是所有面向對象的語言的共同特征,所有面向對象的語言都提供了這種類型。一個有一定規(guī)模的C++程序是由許多類所構成的。
C++支持面向過程的程序設計,又支持面向對象的程序設計。8.1.3類和對象的作用9面向對象的軟件工程是面向對象方法在軟件工程領域的全面應用。它包括:面向對象的分析(OOA)面向對象的設計(OOD)面向對象的編程(OOP)Object-Oriented Programming面向對象的測試(OOT)面向對象的軟件維護(OOSM)8.1.4面向對象的軟件開發(fā)10系統(tǒng)分析系統(tǒng)分析階段應該扼要精確地抽象出系統(tǒng)必須做什么,但是不關心如何去實現。面向對象的系統(tǒng)分析,直接用問題域中客觀存在的事物建立模型中的對象,對單個事物及事物之間的關系,都保留他們的原貌,不做轉換,也不打破原有界限而重新組合,因此能夠很好地映射客觀事物。11設計針對系統(tǒng)的一個具體實現運用面向對象的方法(怎么做?)。其中包括兩方面的工作:把OOA模型直接搬到OOD,作為OOD的一部分針對具體實現中的人機界面、數據存儲、任務管理等因素補充一些與實現有關的部分。12編程OOP工作就是用一種面向對象的編程語言把OOD模型中的每個成分書寫出來,是面向對象的軟件開發(fā)最終落實的重要階段。13測試測試的任務是發(fā)現軟件中的錯誤。在面向對象的軟件測試中繼續(xù)運用面向對象的概念與原則來組織測試,以對象的類作為基本測試單位,可以更準確的發(fā)現程序錯誤并提高測試效率。從執(zhí)行被測軟件的角度:分為靜態(tài)測試和動態(tài)測試 若按照功能分:分為白盒測試(結構)和黑盒測試(功能)軟件測試過程:單元測試、集成測試、驗收測試(確認)和系統(tǒng)測試。軟件調試方法:強行排錯法、回溯法、原因排除法。14維護將軟件交付使用后,工作并沒有完結,還要根據軟件的運行情況和用戶的需求,不斷改進系統(tǒng)。使用面向對象的方法開發(fā)的軟件,其程序與問題域是一致的,因此,在維護階段運用面向對象的方法可以大大提高軟件維護的效率。15在C++中也是先聲明一個類類型,然后用它去定義若干個同類型的對象。對象就是類類型的一個變量。可以說類是對象的模板,是用來定義對象的一種抽象類型。在C++中對象的類型稱為類(class)。類代表了某一批對象的共性和特征。所以,每一個實體都是對象。有一些對象是具有相同的結構和特性的,它們屬于一類。類和對象的關系:類是對象的抽象,不占用內存,而對象是類的具體實例(instance),占用存儲空間。8.2類的聲明和對象的定義
8.2.1類和對象的關系16類是用戶自己定義的類型。如果程序中要用到類類型,必須自己根據需要進行聲明,或者使用別人已設計好的類。
C++標準本身并不提供現成的類的名稱、結構和內容。classStudent//以class開頭{ intnum; charname[20]; charsex;//以上3行是數據成員
voiddisplay()//這是成員函數
{cout<<″num:″<<num<<endl;
cout<<″name:″<<name<<endl;
cout<<″sex:″<<sex<<endl;//以上4行是函數中的操作語句
}};Studentstud1,stud2;//定義了兩個Student類的對象stud1和stud28.2.2聲明類類型17可以看到,類(class)就是對象的類型。實際上,類是一種廣義的數據類型。類這種數據類型中的數據既包含數據,也包含操作數據的函數。不能把類中的全部成員與外界隔離,一般是把數據隱蔽起來,而把成員函數作為對外界的接口??梢詫⑸厦骖惖穆暶鞲臑閏lassStudent//聲明類類型{private://聲明以下部分為私有的
intnum; charname[20]; charsex;public://聲明以下部分為公用的
voiddisplay() {cout<<″num:″<<num<<endl;
cout<<″name:″<<name<<endl;
cout<<″sex:″<<sex<<endl;}};Studentstud1,stud2;//定義了兩個Student類的對象18如果在類的定義中既不指定private,也不指定public,則系統(tǒng)就默認為是私有的。歸納以上對類類型的聲明,可得到其一般形式如下:class類名//C++程序多數先寫public部分,這樣使用戶將 注意力集中在能被外界調用的成員上{private: <私有的數據和成員函數的說明>;public: <公用的數據和成員函數的說明>;};<各成員函數的實現>private和public稱為成員訪問限定符(memberaccessspecifier)。還有一種成員訪問限定符protected(受保護的),用protected聲明的成員稱為受保護的成員,它不能被類外訪問(這點與私有成員類似),但可以被派生類的成員函數訪問。19定義對象也可以有幾種方法:1.先聲明類類型,然后再定義對象classStudent//聲明類類型{private://聲明以下部分為私有的
intnum; charname[20]; charsex;public://聲明以下部分為公用的
voiddisplay() {cout<<″num:″<<num<<endl;
cout<<″name:″<<name<<endl;
cout<<″sex:″<<sex<<endl;}};Studentstud1,stud2;//定義了兩個Student類的對象8.2.3定義對象的方法202.在聲明類類型的同時定義對象classStudent//聲明類類型{public://先聲明公用部分
voiddisplay() {cout<<″num:″<<num<<endl;
cout<<″name:″<<name<<endl;
cout<<″sex:″<<sex<<endl;}private://后聲明私有部分
intnum; charname[20]; charsex;}stud1,stud2;//定義了兩個Student類的對象在定義Student類的同時,定義了兩個Student類的對象。213.不出現類名,直接定義對象class//無類名{private://聲明以下部分為私有的┆
public://聲明以下部分為公用的┆}stud1,stud2;//定義了兩個無類名的類對象直接定義對象,在C++中是合法的、允許的,但卻很少用,也不提倡用。在實際的程序開發(fā)中,一般都采用上面3種方法中的第1種方法。在小型程序中或所聲明的類只用于本程序時,也可以用第2種方法。22類的成員函數(簡稱類函數)是函數的一種,它的用法和作用和函數基本上是一樣的,它也有返回值和函數類型。它與一般函數的區(qū)別只是:它是屬于一個類的成員,出現在類體中。它可以被指定為private(私有的)、public(公用的)或protected(受保護的)。在使用類函數時,要注意調用它的權限(它能否被調用)以及它的作用域(函數能使用什么范圍中的數據和函數)。例如私有的成員函數只能被本類中的其他成員函數所調用,而不能被類外調用。8.3類的成員函數
8.3.1成員函數的性質23成員函數可以訪問本類中任何成員(包括私有的和公用的),可以引用在本作用域中有效的數據。一般的做法是將需要被外界調用的成員函數指定為public,它們是類的對外接口。注意,并非要求把所有成員函數都指定為public。有的函數并不是準備為外界調用的,而是為本類中的成員函數所調用的,就應該將它們指定為private。這種函數的作用是支持其他函數的操作,是類中其他成員的工具函數(utilityfunction),類外用戶不能調用這些私有的工具函數。類的成員函數是類體中十分重要的部分。如果一個類中不包含成員函數,就等同于C語言中的結構體了,體現不出類在面向對象程序設計中的作用。24在前面已經看到成員函數是在類體中定義的。也可以在類體中只寫成員函數的聲明,而在類的外面進行函數定義。如:classStudent{public: voiddisplay();//公用成員函數原型聲明
private:
intnum; stringname; charsex;//以上3行是私有數據成員};voidStudent∷display()//在類外定義display類函數{cout<<″num:″<<num<<endl;//函數體cout<<″name:″<<name<<endl;cout<<″sex:″<<sex<<endl;}Studentstud1,stud2;//定義兩個類對象注意:成員函數在類外定義時,必須在函數名前面加上類名,予以限定(qualifed),“∷”是作用域運算符,用它聲明函數是屬于哪個類的。8.3.2在類外定義成員函數25關于內置(inline)函數,已作過介紹。類的成員函數也可以指定為內置函數。在類體中定義的成員函數的規(guī)模一般都很小,而系統(tǒng)調用函數的過程所花費的時間開銷相對是比較大的。調用一個函數的時間開銷遠遠大于小規(guī)模函數體中全部語句的執(zhí)行時間。為了減少時間開銷,如果在類體中定義的成員函數中不包括循環(huán)等控制結構,C++系統(tǒng)會自動將它們作為內置(inline)函數來處理。也就是說,在程序調用這些成員函數時,并不是真正地執(zhí)行函數的調用過程(如保留返回地址等處理),而是把函數代碼嵌入程序的調用點。這樣可以大大減少調用成員函數的時間開銷。8.3.3inline成員函數26C++要求對一般的內置函數要用關鍵字inline聲明,但對類內定義的成員函數,可以省略inline,因為這些成員函數已被隱含地指定為內置函數。如classStudent{public: voiddisplay() {cout<<″num:″<<num<<endl;
cout<<″name:″<<name<<endl;
cout<<″sex:″<<sex<<endl; }private:
intnum; stringname; charsex;};voiddisplay()也可以寫成inlinevoiddisplay()對在類體內定義的函數,一般都省寫inline。27如果成員函數不在類體內定義,而在類體外定義,系統(tǒng)并不把它默認為內置(inline)函數,如果想將這些成員函數指定為內置函數,應當用inline作顯式聲明。如classStudent{public: inlinevoiddisplay();//聲明此成員函數為內置函數
private:
intnum; stringname; charsex;};inlinevoidStudent∷display()//在類外定義display函數為內置函數{cout<<″num:″<<num<<endl;cout<<″name:″<<name<<endl;cout<<″sex:″<<sex<<endl;}
只有在類外定義的成員函數規(guī)模很小而調用頻率較高時,才將此成員函數指定為內置函數。28用類去定義對象時,系統(tǒng)會為每一個對象分配存儲空間。如果一個類包括了數據和函數,要分別為數據和函數的代碼分配存儲空間。按理說,如果用同一個類定義了10個對象,那么就需要分別為10個對象的數據和函數代碼分配存儲單元,如圖8.4所示。圖8.48.3.4成員函數的存儲方式29 能否只用一段空間來存放這個共同的函數代碼段,在調用各對象的函數時,都去調用這個公用的函數代碼。如圖8.5所示。
圖8.5顯然,這樣做會大大節(jié)約存儲空間。C++編譯系統(tǒng)正是這樣做的,因此每個對象所占用的存儲空間只是該對象的數據部分所占用的存儲空間,而不包括函數代碼所占用的存儲空間。30如果聲明了一個類:classTime{public:
inthour;
intminute;
intsec; voidset() {cin>>a>>b>>c;}};可以用下面的語句來輸出該類對象所占用的字節(jié)數:cout<<sizeof(Time)<<endl;輸出的值是12。這就證明了一個對象所占的空間大小只取決于該對象中數據成員所占的空間,而與成員函數無關。函數代碼是存儲在對象空間之外的。如果對同一個類定義了10個對象,這些對象的成員函數對應的是同一個函數代碼段,而不是10個不同的函數代碼段。31例:8-1-(1).cpp#include"iostream"usingnamespacestd;classTime{public:
inthour;
intminute;
intsec; voidset();};voidTime::set() {cin>>hour>>minute>>sec;}intmain(){ Timet1,t2;
cout<<sizeof(Time)<<endl;
cout<<sizeof(t1)<<endl;
cout<<sizeof(t2)<<endl; return0;}32需要注意的是:雖然調用不同對象的成員函數時都是執(zhí)行同一段函數代碼,但是執(zhí)行結果一般是不相同的。
C++專門設立了一個名為this的指針,不同的對象使用的是同一個函數代碼段,該指針用來指向不同的對象。33在程序中經常需要訪問對象中的成員。訪問對象中的成員可以有3種方法:通過對象名和成員運算符訪問對象中的成員;訪問對象中成員的一般形式為對象名.成員名例如:stud1.num=1001;//假設num已定義為公用的整型數據成員
stud1.display();//正確,調用對象stud1的公用成員函數在類外只能調用公用的成員函數。在一個類中應當至少有一個公用的成員函數,作為對外的接口,否則就無法對對象進行任何操作。8.4對象成員的引用34通過指向對象的指針訪問對象中的成員;用指針訪問對象中的成員的方法有以下程序段:classTime{public://數據成員是公用的
inthour;
intminute;};Timet,*p;//定義對象t和指針變量pp=&t;//使p指向對象tcout<<p->hour;//輸出p指向的對象中的成員hour在p指向t的前提下,p->hour,(*p).hour和t.hour三者等價。通過對象的引用變量訪問對象中的成員。如果已聲明了Time類,并有以下定義語句:Timet1;//定義對象t1Time&t2=t1;//定義Time類引用變量t2,并使之初始化為t1cout<<t2.hour;//輸出對象t1中的成員hour由于t2與t1共占同一段存儲單元(即t2是t1的別名),因此t2.hour就是t1.hour。35
C++通過類來實現封裝性,把數據和與這些數據有關的操作封裝在一個類中。公用成員函數是用戶使用類的公用接口,或者說是類的對外接口。類中被操作的數據是私有的,實現的細節(jié)對用戶是隱蔽的,這種實現稱為私有實現(privateimplementation)。這種“類的公用接口與私有實現的分離”形成了信息隱蔽。軟件工程的一個最基本的原則就是將接口與實現分離,它的好處在于:(1)如果想修改或擴充類的功能,只需修改本類中有關的數據成員和與它有關的成員函數,程序中類外的部分可以不必修改。(2)如果在編譯時發(fā)現類中的數據讀寫有錯,不必檢查整個程序,只需檢查本類中訪問這些數據的少數成員函數。8.5類的封裝性和信息隱蔽
8.5.1公用接口與私有實現的分離36在面向對象的程序開發(fā)中,一般做法是將類的聲明(其中包含成員函數的聲明)放在指定的頭文件中,用戶如果想用該類,只要把有關的頭文件包含進來即可,不必在程序中重復書寫類的聲明,以減少工作量,節(jié)省篇幅,提高編程的效率。由于在頭文件中包含了類的聲明,因此在程序中就可以用該類來定義對象。由于在類體中包含了對成員函數的聲明,在程序中就可以調用這些對象的公用成員函數。為了實現信息隱蔽,對類成員函數的定義一般不放在頭文件中,而另外放在一個文件中。8.5.2類聲明和成員函數定義的分離37例如,可以分別寫兩個文件://student.h(頭文件可以包括:外部變量聲明、函數原型聲明、類聲明、常量聲明、內聯函數和typedef聲明,該頭文件則進行類的聲明)classStudent//類聲明{public: voiddisplay();//公用成員函數原型聲明private:
intnum; charname[20]; charsex;};//student.cpp//在此文件中進行函數的定義#include<iostream>#include“student.h”//不要漏寫此行,否則編譯通不過Usingnamespacestd;voidStudent∷display()//在類外定義display類函數{cout<<″num:″<<num<<endl;
cout<<″name:″<<name<<endl;
cout<<″sex:″<<sex<<endl;}38為了組成一個完整的源程序,還應當有包括主函數的源文件://main.cpp
主函數模塊//#include<iostream>#include“student.h”//將類聲明頭文件包含進來//Usingnamespacestd;intmain(){Studentstud;//定義對象
stud.display();//執(zhí)行stud對象的display函數
return0;}這是一個包括3個文件的程序,組成兩個文件模塊:一個是主模塊main.cpp,一個是student.cpp。在主模塊中又包含頭文件student.h。在預編譯時會將頭文件student.h中的內容取代#include″student.h″行。39請注意:由于將頭文件student.h放在用戶當前目錄中,因此在文件名兩側用雙撇號包起來(″student.h″)而不用尖括號(<student.h>),否則編譯時會找不到此文件。圖8.6。40由于要求接口與實現分離,為軟件開發(fā)商向用戶提供類庫創(chuàng)造了很好的條件。開發(fā)商把用戶所需的各種類的聲明按類放在不同的頭文件中,同時對包含成員函數定義的源文件進行編譯,得到成員函數定義的目標代碼。軟件商向用戶提供這些頭文件和類的實現的目標代碼(不提供函數定義的源代碼)。用戶在使用類庫中的類時,只需將有關頭文件包含到自己的程序中,并且在編譯后連接成員函數定義的目標代碼即可。由于類庫的出現,用戶可以像使用零件一樣方便地使用在實踐中積累的通用的或專用的類,這就大大減少了程序設計的工作量,有效地提高了工作效率。41在面向對象程序理論中,“方法”是指對數據的操作。一個“方法”對應一種操作。顯然,只有被聲明為公用的方法(成員函數)才能被對象外界所激活。外界是通過發(fā)“消息”來激活有關方法的。所謂“消息”,其實就是一個命令,由程序語句來實現。stud.display();就是向對象stud發(fā)出的一個“消息”,通知它執(zhí)行其中的display“方法”(即display函數)。上面這個語句涉及3個術語:對象、方法和消息。stud是對象,display()是方法,語句“stud.display();”是消息。8.5.3面向對象程序設計中的幾個名詞42例8.1最簡單的例子。#include<iostream>usingnamespacestd;classTime//定義Time類{public://數據成員為公用的
inthour;
intminute;
intsec;};intmain(){Timet1;//定義t1為Time類對象
cin>>t1.hour;//輸入設定的時間
cin>>t1.minute;
cin>>t1.sec;
cout<<t1.hour<<″:″<<t1.minute<<″:″<<t1.sec<<endl;//輸出時間
return0;}//運行情況如下:123243↙12:32:438.6類和對象的簡單應用舉例43例8.3將程序用含成員函數的類來處理。#include<iostream>usingnamespacestd;classTime{public: voidset_time();//公用成員函數
voidshow_time();//公用成員函數
private://數據成員為私有
inthour;
intminute;
intsec;};intmain(){ Timet1;//定義對象t1t1.set_time();//調用對象t1的成員函數set_time,向t1的數據成員輸入數據
t1.show_time();//調用對象t1的成員函數show_time,輸出t1的數據成員的值
Timet2;//定義對象t244
t2.set_time();//調用對象t2的成員函數set_time,向t
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 電路分析課程設計案例
- 2024年土方工程車隊租賃合同及車隊車輛保險理賠協(xié)議3篇
- 滑輪初中物理課程設計
- 2024年煤礦作業(yè)員工作合同
- 2024年度帶附加運輸責任限制的貨物裝卸合同2篇
- 2025年山東淄博市臨淄區(qū)紀委監(jiān)委選調工作人員15人歷年管理單位筆試遴選500模擬題附帶答案詳解
- 2025年山東濟南市歷下區(qū)所屬事業(yè)單位招聘95人歷年管理單位筆試遴選500模擬題附帶答案詳解
- 2025年山東棗莊市市直事業(yè)單位招聘工作人員128人歷年管理單位筆試遴選500模擬題附帶答案詳解
- 2025年山東德州市事業(yè)單位引進百名博士研究生199人管理單位筆試遴選500模擬題附帶答案詳解
- 2024年物業(yè)全面服務包干制合同3篇
- 出納移交工作明細表(標準通用)
- 地基處理記錄表
- 形式與政策論文
- 單位檔案盒標簽模板可修改打印
- 人教版八年級人文地理下冊知識點整理(2021版)
- (歷年中考)江蘇省蘇州市中考數學試題含答案
- 低壓鑄造典型缺陷及防止
- 2015年日歷表(超清晰A4打印版)
- 剪式汽車舉升機設計
- 健康證體檢表
- 廣東省涉水建設項目洪水影響評價 - gd
評論
0/150
提交評論