知识点总结(什么是面向对象)
一、這個對象指的是什么 (個人理解,)
這個對象指的不是C#中的實例,這個對象是個抽象的,在我的理解中,面向對象這個對象是我們需要實現的東西,簡單說就比如我現在需要編寫一段游戲代碼,就拿目前最火的LOL來講,在游戲中有100+的英雄,每個英雄都有屬于自己的屬性比如說
這個時候我們就將這個英雄作為一個對象,100+的英雄就調用這一個封裝好的英雄對象來實現這100+的英雄,否則需要重新寫100+的重復代碼。
二、為什么要面向對象?
面向對象是想要解決系統的可維護性、可擴展性、可重用性,我們在考慮下為什么要用面向對象來解決呢?
作者:匿名用戶
鏈接:https://www.zhihu.com/question/27468564/answer/101951302
來源:知乎
當軟件還非常簡單的時候,我們只需要面向過程編程:
定義函數
函數一
函數二
函數三
函數四
定義數據
數據一
數據二
數據三
數據四
最后
各種函數,數據的操作。
當軟件發展起來后,我們的軟件變得越來越大,代碼量越來越多,復雜度遠超Hello World的時候,我們的編寫就有麻煩了:
函數和數據會定義得非常多,面臨兩個問題。
首先是命名沖突,英文單詞也就那么幾個,可能寫著寫著取名時就沒合適的短詞用了,為了避免沖突,只能把函數名取得越來越長。
然后是代碼重復,比如你做一個計算器程序,你的函數就要確保處理的是合理的數據,這樣最起碼加減乘除四個函數里,你就都要寫對參數進行檢測的代碼,寫四遍或者復制粘貼四遍不會很煩,但多了你就痛苦了,而且因為這些檢測代碼是跟你的加減乘除函數的本意是無關的,卻一定要寫在那里,使代碼變得不好閱讀,意圖模糊。
就算一個網絡小說的作者,他每次寫新章節時也不大可能直接打開包含著前面幾百章文字的文檔接著寫。更正常的做法是新建一個文檔,寫新的一章,為的是減小復雜性,減少干擾。更何況代碼那么復雜那么容易出錯的東西。
隨著軟件業的發展,解決辦法就要出來了。
代碼重復,我們可以用函數里面調用函數的方法,比如把檢測代碼抽出來成一個獨立函數,然后加減乘除四個函數運行時只要調用一下檢測函數對參數進行檢查就可以了。分布在四個函數里的重復代碼變成了一個函數,是不是好維護多了。
命名沖突,我們就把這一堆函數們進行分類吧。
比如沒有分類時候,我們取名只能取名:
檢測
整數加
整數減
整數乘
整數除
復數加
復數減
復數乘
復數除
小數加
...
進行歸類后
整數 {
檢測
加
減
乘
除
}
復數 {
檢測
加
減
乘
除
}
小數 {
檢測
加
減
乘
除
}
分數 {
檢測
加
減
乘
除
}
是不是一種叫做類的概念就呼之欲出了,這樣我們打開一個整數類代碼文件,里面就是簡簡單單的加減乘除四個函數,簡單清晰而不會跟外面的其他加減乘除函數命名沖突。
當然,進行歸類后,又有各種的問題和解決辦法了,比如四個類中的檢測也是應該提取出來的,所以簡單的起因最終發展出什么繼承衍生之類挺復雜的一套編程模式。然后學術界那幫人就又亂起什么高大上的名字了,所謂面向對象程序設計去禍害大學里那幫孩子。
就算未來出來一個什么新的面向XX編程,我們也不用多想為什么會出現,肯定是為了解決麻煩而已。
上面進行歸類后,代碼其實還是不好維護的,然后我們就繼續提取為:
數 {
檢測
加
減
乘
除
}
整數 {
沿用上面數的設計
}
小數 {
沿用上面數的設計
}
所謂繼承,就是數這個類的整體設計,沿用給整數,分數小數這些類,作為他們的編寫大綱去編寫加減乘除這些函數的具體代碼。根據整數,分數,小數各自的性質,做出各自的調整。
這時數這個類,如果你給它里面的加減乘除函數的寫了一些很粗糙簡單的代碼,就叫做父類,基礎類。子類們“繼承”了父類(把代碼進行了復雜化)。
如果沒寫,那這個類其實就只是個設計圖,叫做抽象類。子類們“實現”了抽象類(把空空的設計變成了具體代碼)。
模版是什么?像C++這種復雜成狗的語言是強類型的,就是給變量進行了類型區分的,比如整數類型,雙整數類型。很明顯這兩種變量所能容納的數據體積是不一樣的,單個函數不能通吃多種類型的參數,我們就可能會面臨下面兩套代碼并存的局面。
單整數類 {
單整數加
單整數減
單整數乘
單整數除
}
雙整數類 {
雙整數加
雙整數減
雙整數乘
雙整數除
}
所以C艸跟其他強類型語言為我們提供了一個所謂模版功能:
<變量類型>整數 {
<變量類型>加
<變量類型>減
<變量類型>乘
<變量類型>除
}
整數類等于把變量類型設置為整數,套上模版 雙整數類等于把變量類型設置為雙整數,套上模版
這樣就寫了一份代碼,得到了兩份類的代碼。
當然,弱類型的編程語言,比如JavaScript或者PHP是沒有這種煩惱的,因為變量沒有類型之分。但變量類型有時候還是很重要的,弱類型語言里就會出現類似數加字符串這種運算,可能并不是程序員的預期和本意,所以比起強類型性語言而言經常會出現很多無聊的BUG。
再更新:
上面發展出了父類之后,我們發現編程還是有問題的,小數類:
小數類 {
加
減
乘
除
}
如果我們需要一個能自動實現結果四舍五入的小數計算類,同時又需要一個不需要的,怎么辦呢,難道要寫兩個類嗎?不要。
所以做出了“實例”或者“對象”這一東西,首先把類改成:
小數類 {
標識變量:是否四舍五入
標識變量:是否限定小數點后位數
構造函數(設置上面的標識)
加(會根據上面兩個標識變量輸出不同結果)
減(會根據上面兩個標識變量輸出不同結果)
乘(會根據上面兩個標識變量輸出不同結果)
除(會根據上面兩個標識變量輸出不同結果)
}
這樣,我們就寫一個類,但是通過構造函數,把一份代碼,構造出了行為稍微有點不同的兩個實例供我們使用,這時候名詞來了,不能進行實例化微調化的類,叫做靜態類,函數們的行為是固定的。不能實例化的類,其實只是函數們的一個集合歸納,只是對函數進行了整理,功能的強大和編碼的自由靈活度是不夠的。
能夠進行實例化,變化出各種行為各自不大一樣的實例的類,我們一般就把它們叫做類了,因為最常見。
看完之后是不是覺得恍然大悟呢?面向對象減少了我們的代碼書寫量,將可以重復使用的代碼進行封裝,
講到這里再說下面向對象的三大特征,他們分別是封裝,繼承和多態
封裝:找到變化并且把它封裝起來,你就可以在不影響其它部分的情況下修改或擴展被封裝的變化部分,這是所有設計模式的基礎,就是封裝變化,因此封裝的作用,就解決了程序的可擴展性。
繼承:子類繼承父類,可以繼承父類的方法及屬性,實現了多態以及代碼的重用,因此也解決了系統的重用性和擴展性,但是繼承破壞了封裝,因為他是對子類開放的,修改父類會導致所有子類的改變,因此繼承一定程度上又破壞了系統的可擴展性,所以繼承需要慎用,只有明確的IS-A關系才能使用,同時繼承在在程序開發過程中重構得到的,而不是程序設計之初就使用繼承,很多面向對象開發者濫用繼承,結果造成后期的代碼解決不了需求的變化了。因此優先使用組合,而不是繼承,是面向對象開發中一個重要的經驗。
多態:接口的多種不同的實現方式即為多態。接口是對行為的抽象,剛才在封裝提到,找到變化部分并封裝起來,但是封裝起來后,怎么適應接下來的變化?這正是接口的作用,接口的主要目的是為不相關的類提供通用的處理服務,我們可以想象一下。比如鳥會飛,但是超人也會飛,通過飛這個接口,我們可以讓鳥和超人,都實現這個接口,這就實現了系統的可維護性,可擴展性。
因此面向對象能實現人們追求的系統可維護性,可擴展性,可重用性。面向對象是一種編程思想,起初,“面向對象”是專指在程序設計中采用封裝、繼承、多態等設計方法,但面向對象的思想已經涉及到軟件開發的各個方面,比如現在細分為了面向對象的分析(OOA),面向對象的設計(OOD),面向對象的編程實現(OOP)
三、面向對象的實現
面向對象是一種思想,他讓我們在分析和解決問題時,把思維和重點轉向現實中的載體中來,它分為面向對象的分析(OOA),面向對象的設計(OOD),面向對象的編程實現(OOP)三個大的步驟。
1、首先是分析需求,先不要思考怎么用程序實現它,先分析需求中穩定不變的內容都是些什么,這些內容之間的關系是什么。
2、把第一步分析出來的需求,通過進一步擴充模型,變成可實現的、符合成本的、模塊化的、低耦合高內聚的模型。
3、開始動手實現這個模型~
總結
以上是生活随笔為你收集整理的知识点总结(什么是面向对象)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2016年11月13日周工作知识点总结
- 下一篇: DNS之BIND使用小结(Forward