網頁鏈接
Ⅱ 《java編程思想第五版》pdf下載在線閱讀全文,求百度網盤雲資源
《java編程思想第五版》網路網盤pdf最新全集下載:
鏈接: https://pan..com/s/1O_tFXTl0TMBm_gfTdcxJbg
Ⅲ 什麼是面向對象編程思想
面相對象不是某一種語言的特性,而是一種編程思想。面向對象的編程的主要思想是把構成問題的各個事物分解成各個對象,建立對象的目的不是為了完成一個步驟,而是為了描述一個事物在解決問題的過程中經歷的步驟和行為。
面向對象的三大特徵分別是:封裝、繼承、多態,這三者是面向對象編程的基本要素
面向對象編程(Object-oriented Programming,縮寫:OOP)
是軟體工程中一種具有對象概念的編程範式(Programming Paradigm),同時也是一種程序開發的抽象方針,與之對應的編程範式還有:函數式編程(Functional Programming)、過程式編程(Proceral Programming)、響應式編程(Reactive Programming)等。
Ⅳ 31. 面向對象的思想主要包括什麼
前面已說明設計程序就是編寫程序欲解決的問題的描述,也就是編寫論調。而論調可以只用「名詞性概念」和「動詞性概念」表現出來,對象又正好是「名詞性概念」的實現,而利用前面說的沒有成員變數的類來映射「動詞性概念」就可以將其轉換為對象。因此,一個世界,可以完全由對象組成,而將演算法所基於的世界只用對象表現出來,再進行後續代碼的編寫,這種編程方法就被稱作面向對象的編程思想。
注意,先設計演算法應基於的世界,再全部用對象將其表述出來,然後再設計演算法,最後映射為代碼。但前面在編寫商人過河問題時是直接給出演算法的,並沒有設計世界啊?其實由於那個問題的過於簡單,我直接下意識地設計了世界,並且用前面所說的河岸論來描述它。應注意世界的設計完全依賴於問題,而准確地說,前面我並沒有設計世界,而是設計了河岸論來描述問題。
接著,由於對象就是實例,因此以對象來描述世界在C++中就是設計類,通過類的實例來組合表現世界。但應注意,面向對象是以對象來描述世界,但也描述演算法,因為演算法也會提出一些需要被映射的概念,如前面商人過河問題的演算法中的過河方案。但切記,當描述演算法時操作了描述世界時定義的類,則一定要保持那個類的設計,不要因為演算法中對那個類的實例的操作過於復雜而將那部分演算法映射為這個類的一個成員函數,因為這嚴重遮蔽了演算法的實現,破壞了程序的架構。如一個演算法是讓汽車原地不停打轉,需要復雜的操作,那麼難道給汽車加一個功能,讓它能原地不停地打轉?!這是在設計類的時候經常犯的錯誤,也由於這個原因,一個面向對象編寫的代碼並不是想像的只由類組成,其也可能由於將演算法中的某些操作映射成函數而有大量的全局函數。請記住:設計類時,如果是映射世界裡的概念,不要考慮演算法,只以這個世界為邊界來設計它,不要因為演算法里的某個需要而給它加上錯誤的成員。
因此,將「名詞性概念」映射成類,「名詞性概念」的屬性和狀態映射為成員變數,「名詞性概念」的功能映射為成員函數。那麼「動詞性概念」怎麼辦?映射成沒有成員變數的類?前面也看見,由於過於別扭,實際中這種做法並不常見(STL中也只是將其作為一種技巧),故經常是將它映射為函數,雖然這有背於面向對象的思想,但要易於理解得多,進而程序的架構要簡明得多。
隨著面向對象編程思想的問世,一種全新的設計方式誕生了。由於它是如此的好以至於廣為流傳,但理解的錯誤導致錯誤的思想遍地而生,更糟糕的就是本末倒置,將這個設計方式稱作面向對象的編程思想,它的名字就是封裝。
封裝
先來看現在在各類VC教程中關於對象的講解中經常能看見的如下的一個類的設計。
class Person
{ private: char m_Name[20]; unsigned long m_Age; bool m_Sex;
public: const char* GetName() const; void SetName( const char* );
unsigned long GetAge() const; void SetAge( unsigned long );
bool GetSex() const; void SetSex( bool );
};
上面將成員變數全部定義為private,然後又提供三對Get/Set函數來存取上面的三個成員變數(因為它們是private,外界不能直接存取),這三對函數都是public的,為什麼要這樣?那些教材將此稱作封裝,是對類Person的內部內存布局的封裝,這樣外界就不知道其在內存上是如何布局的並進而可以保證內存的有效性(只由類自身操作其實例)。
首先要確認上面設計的荒謬性,它是正宗的「有門沒鎖」毫無意義。接著再看所謂的對內存布局的封裝。回想在《C++從零開始(十)》中說的為什麼每個要使用類的源文件的開頭要包含相應的頭文件。假設上面是在Person.h中的聲明,然後在b.cpp中要使用類Person,本來要#include "Person.h",現在替換成下面:
class Person
{ public: char m_Name[20]; unsigned long m_Age; bool m_Sex;
public: const char* GetName() const; void SetName( const char* );
unsigned long GetAge() const; void SetAge( unsigned long );
bool GetSex() const; void SetSex( bool );
};
然後在b.cpp中照常使用類Person,如下:
Person a, b; a.m_Age = 20; b.GetSex();
這里就直接使用了Person::m_Age了,就算不做這樣蹩腳的動作,依舊#include "Person.h",如下:
struct PERSON { char m_Name[20]; unsigned long m_Age; bool m_Sex; };
Person a, b; PERSON *pP = ( PERSON* )&a; pP->m_Age = 40;
上面依舊直接修改了Person的實例a的成員Person::m_Age,如何能隱藏內存布局?!請回想聲明的作用,類的內存布局是編譯器生成對象時必須的,根本不能對任何使用對象的代碼隱藏有關對象實現的任何東西,否則編譯器無法編譯相應的代碼。
那麼從語義上來看。Person映射的不是真實世界中的人的概念,應該是存放某個資料庫中的某個記錄人員信息的表中的記錄的緩沖區,那麼緩沖區應該具備那三對Get/Set所代表的功能嗎?緩沖區是緩沖數據用的,緩沖後被其它操作使用,就好像箱子,只是放東西用。故上面的三對Get/Set沒有存在的必要,而三個成員變數則不能是private。當然,如果Person映射的並不是緩沖區,而在其它的世界中具備像上面那樣表現的語義,則像上面那樣定義就沒有問題,但如果是因為對內存布局的封裝而那樣定義類則是大錯特錯的。
上面錯誤的根本在於沒有理解何謂封裝。為了說明封裝,先看下MFC(Microsoft Foundation Class Library——微軟功能類庫,一個定義了許多類的庫文件,其中的絕大部分類是封裝設計。關於庫文件在說明SDK時闡述)中的類CFile的定義。從名字就可看出它映射的是操作系統中文件的概念,但它卻有這樣的成員函數——CFile::Open、CFile::Close、CFile::Read、CFile::Write,有什麼問題?這四個成員函數映射的都是對文件的操作而不是文件所具備的功能,分別為打開文件、關閉文件、從文件讀數據、向文件寫數據。這不是和前面說的成員函數的語義相背嗎?上面四個操作有個共性,都是施加於文件這個資源上的操作,可以將它們叫做「被功能」,如文件具有「被打開」的功能,具有「被讀取」的功能,但應注意它們實際並不是文件的功能。
按照原來的說法,應該將文件映射為一個結構,如FILE,然後上面的四個操作應映射成四個函數,再利用名字空間的功能,如下:
namespace OFILE
{
bool Open( FILE&, … ); bool Close( FILE&, … );
bool Read( FILE&, … ); bool Write( FILE&, … );
}
上面的名字空間OFILE表示裡面的四個函數都是對文件的操作,但四個函數都帶有一個FILE&的參數。回想非靜態成員函數都有個隱藏的參數this,因此,一個了不起的想法誕生了。
將所有對某種資源的操作的集合看成是一種資源,把它映射成一個類,則這個類的對象就是對某個對象的操作,此法被稱作封裝,而那個類被稱作包裝類或封裝類。很明顯,包裝類映射的是「對某種資源的操作」,是一抽象概念,即包裝類的對象都是無狀態對象(指邏輯上應該是無狀態對象,但如果多個操作間有聯系,則還是可能有狀態的,但此時它的語義也相應地有些變化。如多一個CFile::Flush成員函數,用於刷新緩沖區內容,則此時就至少有一個狀態——緩沖區,還可有一個狀態記錄是否已經調用過CFile::Write,沒有則不用刷新)。
現在應能了解封裝的含義了。將對某種資源的操作封裝成一個類,此包裝類映射的不是世界中定義的某一「名詞性概念」,而是世界的「動詞性概念」或演算法中「對某一概念的操作」這個人為定出來的抽象概念。由於包裝類是對某種資源的操作的封裝,則包裝類對象一定有個屬性指明被操作的對象,對於MFC中的CFile,就是CFile::m_hFile成員變數(類型為HANDLE),其在包裝類對象的主要運作過程(前面的CFile::Read和CFile::Write)中被讀。
有什麼好處?封裝提供了一種手段以將世界中的部分「動詞性概念」轉換成對象,使得程序的架構更加簡單(多條「動詞性概念」變成一個「名詞性概念」,減少了「動詞性概念」的數量),更趨於面向對象的編程思想。
但應區別開包裝類對象和被包裝的對象。包裝類對象只是個外殼,而被包裝的對象一定是個具有狀態的對象,因為操作就是改變資源的狀態。對於CFile,CFile的實例是包裝類對象,其保持著一個對被包裝對象——文件內核對象(Windows操作系統中定義的一種資源,用HANDLE的實例表徵)——的引用,放在CFile::m_hFile中。因此,包裝類對象是獨立於被包裝對象的。即CFile a;,此時a.m_hFile的值為0或-1,表示其引用的對象是無效的,因此如果a.Read( … );將失敗,因為操作施加的資源是無效的。對此,就應先調用a.Open( … );以將a和一特定的文件內核對象綁定起來,而調用a.Close( … );將解除綁定。注意CFile::Close調用後只是解除了綁定,並不代表a已經被銷毀了,因為a映射的並不是文件內核對象,而是對文件內核對象操作的包裝類對象。
如果仔細想想,就會發現,老虎能夠吃兔子,兔子能夠被吃,那這里應該是老虎有個功能是「吃兔子」還是多個兔子的包裝類來封裝「吃兔子」的操作?這其實不存在任何問題,「老虎吃兔子」和「兔子被吃」完全是兩個不同的操作,前者涉及兩種資源,後者只涉及一種資源,因此可以同時實現兩者,具體應視各自在相應世界中的語義。如果對於真實世界,則可以簡略地說老虎有個「吃」的功能,可以吃「肉」,而動物從「肉」和「自主能動性」多重繼承,兔子再從動物繼承。這里有個類叫「自主能動性」,指動物具有意識,能夠自己動作,這在C++中的表現就是有成員函數的類,表示有功能可以被操作,但收音機也具有調台等功能,難道說收音機也能自己動?!這就是世界的意義——運轉。
方法——世界的驅動方式
演算法就是方法,前面已說過其由操作和被操作的資源組成,即資源的類型和操作的類型。方法指出如何使用世界中定義出的各種操作,但並不執行。由前面的闡述,世界可以只由對象組成,當對象產生後,世界中所有對象的狀態和屬性,即成員變數,的一份拷貝,稱作世界的狀態的一份快照,而世界的狀態的變化稱作世界的運轉。世界的狀態就是世界中所有對象的狀態和屬性,要改變它,就是要執行世界定義的操作,但只能通過方法指出如何執行它以改變世界的狀態,進而驅動世界,即使世界定義的操作被執行才能驅動世界。
上面越說越遠了,感覺虛得很,有什麼意義?考慮為什麼要提出世界這個概念。世界是我們欲編程解決的問題所基於的規則集合體,而設計程序就是設計描述世界的論調,然後在這個論調上設計演算法,編寫出代碼,執行代碼,得到結果。「得到結果」?!什麼是結果?即世界最終狀態中的某一部分,如求圓周率的值。這其實是目的,但值得注意的是目的不止這種。代碼執行的過程往往是另一種目的,如將數據保存到某個文件中;將文件打開編輯再保存等,這種目的並不關心世界的狀態最後如何。而世界的狀態的變化過程,也就是世界的運轉則是另一種非常流行的目的——電子游戲。
不管什麼樣的目的,都需要改變世界的狀態,即要驅動世界運轉,也就必須使世界定義的操作被執行,而這只能通過方法來實現。因此在設計演算法時,也就決定了驅動世界的方式。
對於上面的第一種目的,由於是要看世界的最終狀態,因此一直連續執行操作到最後。在《C++從零開始(八)》中給出的商人過河的例子就在通過演算法得到結果後直接調用printf列印出結果並結束。對於第二種目的,由於要的是執行的過程,因此也可直接連續執行操作到完。但這種目的往往要求由用戶決定何時執行且執行不止一段代碼,如文件打開後,直到用戶給出命令(通過鍵盤或滑鼠或其它輸入方式)後才進行編輯操作,且用戶可能隨機地執行不同的編輯操作,最後也由用戶決定是否保存文件。這種世界的運轉完全由用戶控制的世界驅動方式稱為用戶驅動方式。這里的演算法僅僅是如何打開、保存文件,如何編輯數據,但由於決定是用戶驅動方式,則演算法就必須修改以實現這種驅動方式。再看第三種目的,要的是世界的狀態的變化,則前面兩種都可以。但很明顯,第一種變化過程不能持續,連續執行完就完;第二種由用戶驅動,則太麻煩。因此往往都會有個循環,在游戲編程中一般稱其為主循環,每次循環都按照一定的規則改變世界中部分對象的狀態,此稱作循環驅動方式。每次循環,都會被改變狀態的對象就被稱作具有自主能動性,如前面提到的動物的實例。除此以外的就不稱作具有自主能動性,如前面提到的收音機的實例。同樣,游戲中的演算法依舊不會涉及到上面提到的循環驅動方式,因此必須修改演算法以實現循環驅動方式。
上面將那麼多隻為了說明一點,已經不能再如《C++從零開始(八)》中說的那幾步來編寫程序了,下面給出一個方法。
1. 當得到一個問題,應同時得到這個問題的演算法(程序員並不是科學家),或由客戶給出或由於過於簡單而直接得出。
2. 由問題抽象設計出它的描述,即前面說的論調,也就是所謂的程序設計。
3. 將之前給出的演算法用剛設計出的論調進行描述,並完善這個論調(因為演算法可能帶入一些原來世界中並不存在的概念)。
4. 由需要決定使用何種世界驅動方式,並實現以完善演算法和論調(世界的驅動方式也可能帶入一些原來並不存在的概念)。
Ⅳ 《java面向對象編程第二版》pdf下載在線閱讀全文,求百度網盤雲資源
《java面向對象編程第二版》網路網盤pdf最新全集下載:
鏈接:https://pan..com/s/1fTqz_Grp-TJ-DZfUM80YpA
Ⅵ 簡述面向對象編程思想的三大特徵
1*繼承
繼承是一種聯合類的層次模型,並且允許和鼓勵類的重用,它提供了一種明確表達共性的方法。對象的一個新類可以從現有的類派中產生這個過程叫做類繼承。新類繼承了原始類的特性,新類成為原始類的派生類即子類,而原始類稱為新類的基類即父類。派生類可以從它的基類那裡繼承方法和實例變數,並且類可以修改或增加新的方法使之更加適合特殊的需求。
2*封裝
封裝是把過程和數據包圍起來,對數據的訪問只能通過已定義的畫面。面對對象計算始終與這個基礎概念及現實世界可以被描繪成一系列完全自治封閉的對象,這些對象通過一個受保護的介面訪問其他對象。
3*多態性
多態性是指不同類的對象對同一消息做出響應多態性包括參數化多態性和包含多態性。多態性語言具有靈活抽象行為共享代碼共享的優勢很好地解決了應用程序函數同名問題。
Ⅶ java什麼是面向對象編程思想
面向對象思想是相對於C語言中的面向過程編程思想。我們用java做一件事,只用去new一個對象,並且去調用這個對象的方法,就可以實現我們所要的業務,而這個對象的具體方法做了什麼,具體過程,我們就不用去關注了!這就是面向對象編程思想。
Ⅷ java編程思想第五版 pdf(費掃描版)
這里有中文版第四版網頁鏈接,高清帶書簽,請參考