摘要:摘要本文章關(guān)注點是理解面向?qū)ο蟾拍?,從抽象的角度上去理解對象,重點包括理解對象的作用,以及理解面向?qū)ο蟮娜筇卣鞣庋b,繼承,多態(tài)。特性多態(tài)不同對象以自己的方式響應(yīng)相同的消息的能力叫做多態(tài)。
摘要:本文章關(guān)注點是理解面向?qū)ο蟾拍睿瑥某橄蟮慕嵌壬先ダ斫鈱ο?,重點包括理解對象的作用,以及理解面向?qū)ο蟮娜筇卣鳎ǚ庋b,繼承,多態(tài))。本文重點關(guān)注的是理解概念。
在理解面向?qū)ο笾?,首先回答幾個問題
1. 什么是對象,類
類,即類型的意思,而每一個對象都是某類(類型)的具體實例;比如鳥和魚,都是具體的對象,都是屬于動物這個類;
對象最簡單的描述就是:對象具有狀態(tài)、行為、和標(biāo)志;
具有狀態(tài)異味著著對象可以擁有內(nèi)部數(shù)據(jù);
行為即方法;
標(biāo)志即對象可以唯一的與其他對象區(qū)分開來,有些類似身份證的作業(yè);
2. 為什么要面向?qū)ο笠约皩ο蟮淖饔?/strong>
在面向?qū)ο螽a(chǎn)生之前,最為熟知的是面向過程的編程,大學(xué)的入門課程C語言就是如此;
“面向過程(結(jié)構(gòu)化編程)是以功能為目標(biāo)導(dǎo)向來設(shè)計構(gòu)造應(yīng)用系統(tǒng),這種做法導(dǎo)致我們設(shè)計程序時,不得不將客體所構(gòu)成的現(xiàn)實世界映射到由功能模塊組成的解空間中,這種轉(zhuǎn)換過程,背離了人們觀察和解決問題的基本思路。
可見結(jié)構(gòu)化設(shè)計在設(shè)計系統(tǒng)的時候,無法解決重用、維護、擴展的問題,而且會導(dǎo)致邏輯過于復(fù)雜,代碼晦澀難懂。于是人們就想,能不能讓計算機直接模擬現(xiàn)實的環(huán)境,用人類解決問題的思路,習(xí)慣,步驟來設(shè)計相應(yīng)的應(yīng)用程序?這樣的程序,人們在讀它的時候,會更容易理解,也不需要再把現(xiàn)實世界和程序世界之間來回做轉(zhuǎn)換。
與此同時,人們發(fā)現(xiàn),在現(xiàn)實世界中存在的客體是問題域中的主角,所謂客體是指客觀存在的對象實體和主觀抽象的概念,這種客體具有屬性和行為,而客體是穩(wěn)定的,行為不穩(wěn)定的,同時客體之間具有各種聯(lián)系,因此面向客體編程,比面向行為編程,系統(tǒng)會更穩(wěn)定,在面對頻繁的需求更改時,改變的往往是行為,而客體一般不需要改變,所以我們就把行為封裝起來,這樣改變時候只需要改變行為即可,主架構(gòu)則保持了穩(wěn)定。 ”[1]
那抽象出的對象的角色是什么呢?
對象可以理解為模擬中我們概念中的客體,因此對象的存在的目的就是為提供服務(wù),服務(wù)鏈結(jié)構(gòu)可以多樣化。比如汽車為司機服務(wù),而零件商家為汽車服務(wù)(提供汽車零件)。
"將對象看做是服務(wù)提供者有一個好處就是有助于提高對象的內(nèi)聚性。"[2]
3. 面向?qū)ο笕筇匦?/strong>
面向?qū)ο蟮娜筇匦缘氖抢斫饷嫦驅(qū)ο蟮年P(guān)鍵點。
特性1: 封裝性
首先要問為什么要封裝以及封裝什么?
封裝的的原因在于:封裝可以讓使用者看不到具體的實現(xiàn)細(xì)節(jié),創(chuàng)建者可以不用擔(dān)心被使用者誤改,從而減少程序Bug;
而且,允許庫設(shè)計工作者可以改變程序內(nèi)部結(jié)構(gòu)而不擔(dān)心影響客戶端。創(chuàng)建者改動需要調(diào)用者改動代碼的現(xiàn)象特別是以前很常見的。
同時,客戶端的目標(biāo)也更明確:客戶端程序員不關(guān)心具體的實現(xiàn),只關(guān)心拿創(chuàng)建者的接口的功能是什么。
封裝的內(nèi)容包括三個方面:
(1)把自己的數(shù)據(jù)和方法只讓可信的類或者對象操作,即隱藏或者暴漏數(shù)據(jù)、接口。
(2)"找到變化并且把它封裝起來,你就可以在不影響其它部分的情況下修改或擴展被封裝的變化部分,這是所有設(shè)計模式的基礎(chǔ),就是封裝變化,因此封裝的作用,就解決了程序的可擴展性"[1]
(3)現(xiàn)實寫代碼過程中,更多接觸的是:找到重復(fù)度高的,對代碼可重用的部分進(jìn)行封裝;
特性2: 繼承
面向?qū)ο缶幊?OOP)一個主要功能就是“繼承”。繼承它可以使用現(xiàn)有類的所有功能,并在無需重新編寫原來的類的情況下可以復(fù)用基類的方法或者對這些功能進(jìn)行擴展。
在考慮使用繼承時,有一點需要注意,那就是兩個類之間的關(guān)系應(yīng)該是“屬于”關(guān)系。例如,Cat,Dog,因此這兩個類都可以繼承 Animal 類。否則,沒有這種關(guān)系的就不要繼承了。
接下來,理解下is-a和is-like-a關(guān)系
對于繼承有這么一個爭論:繼承應(yīng)當(dāng)只覆蓋基類(并且不添加基類中沒有的新成員函數(shù))嗎?這就意味著派生類與基類是完全相同的類型,因為它們有相同的接口。結(jié)果是,我們可以用派生類的對象代替基類的對象。這被認(rèn)為是純粹替代(pure substitution),常常被稱做替代原則(substitution principle)。在某種意義上,這是對待繼承的理想方法。我們常把基類和派生類之間的關(guān)系看做是一個“is-a(是)”關(guān)系,因為我們可以說“圓形是一個形體”。對繼承的一種測試方法就是看我們是否可以說這些類有“is-a”關(guān)系,而且還有意義。
但是,有時需要向一個派生類型添加新的接口元素,這樣就擴展了接口。這個新類型和基類不完全相同了,而且這些新接口元素不能從基類訪問。這可以描述為“is-like-a(像)”關(guān)系;新類型有老類型的接口,但還包含其他函數(shù),所以不能說它們完全相同[3]。
同時,繼承雖然可以復(fù)用基類的方法/屬性,但是很多時候的濫用導(dǎo)致的問題太多,比如覆蓋基類后,子類默認(rèn)覆蓋相同名字的父類方法。繼承是中非必要的話就不需要覆蓋了,是一定必要的時候明確指出來,Kotlin語言中繼承基類后,要明確指出覆蓋的方法。
繼承的缺點[4]:
a.破壞封裝,子類與父類之間緊密耦合,子類依賴于父類的實現(xiàn),子類缺乏獨立性
b.支持?jǐn)U展,但是往往以增加系統(tǒng)結(jié)構(gòu)的復(fù)雜度為代價
...
繼承使用原則:
A.繼承樹的層次不可太多,盡量保持在2-3層,首先過多的繼承會導(dǎo)致對象模型的機構(gòu)太復(fù)雜,難以理解,增加了開發(fā)和設(shè)計的難度,如果子類和父類之間還有頻繁的方法和屬性覆蓋,更增加了多態(tài)機制的難度。其次影響系統(tǒng)的可擴展性,繼承樹的層次越多在繼承樹上增加一個新的繼承分支就需要創(chuàng)建更多的類。
B.使用繼承樹上的類時應(yīng)該盡可能把引用變量聲明為繼承樹的上層類型,首先上層類型定義了下層子類都擁有的屬性和方法并且盡可能為多數(shù)方法提供默認(rèn)實現(xiàn)從而提高代碼的可重用性。其次上層類型代表一種服務(wù)接口描述系統(tǒng)所能提供的服務(wù),父類不一定實現(xiàn)這個服務(wù),提高系統(tǒng)的松耦合及系統(tǒng)本身的可維護性。
JAVA為什么是單繼承結(jié)構(gòu)?
在單繼承中,所有對象都具有一個共同的接口,所以他們歸根到底屬于同一基本類型。而多繼承(C++)是無法保證所有對象都屬于同一基本類型。對象的創(chuàng)建和參數(shù)的傳遞相對來說變得簡單,而且使得垃圾回收器的實現(xiàn)變得容易很多,由于所有對象有其類型的基本信息,因此不會出現(xiàn)無法確認(rèn)對象類型而陷入僵局[5](通俗理解就是我系統(tǒng)運行后,不知道哪個類型的對象在work)。
特性3:多態(tài)
不同對象以自己的方式響應(yīng)相同的消息的能力叫做多態(tài)。多態(tài)性(polymorphisn)允許你將父對象設(shè)置成為和一個或更多的他的子對象相等的技術(shù),賦值之后,父對象就可以根據(jù)當(dāng)前賦值給它的子對象的特性以不同的方式運作。簡單的說,就是一句話:允許將子類類型的指針賦值給父類類型的指針。
與多態(tài)相關(guān)的具體是覆蓋,重載。
覆蓋,是指子類重寫父類的函數(shù)。
重載,是指允許存在多個同名函數(shù),而這些函數(shù)的參數(shù)表不同(或許參數(shù)個數(shù)不同,或許參數(shù)類型不同,或許兩者都不同)。
區(qū)分前期綁定和后期綁定
前期綁定,在程序執(zhí)行前根據(jù)編譯時類型綁定,調(diào)用開銷較小,如C語言只有前期綁定這種方法調(diào)用。
后期綁定,是指在運行時根據(jù)對象的類型進(jìn)行綁定,又叫動態(tài)綁定或運行時綁定。實現(xiàn)后期綁定,需要某種機制支持,以便在運行時能判斷對象的類型,調(diào)用開銷比前期綁定大。
Java中的static方法和final方法(private屬于final方法,詳細(xì)的解釋見《Java編程思想》)屬于前期綁定,子類無法重寫final方法,成員變量(包括靜態(tài)及非靜態(tài))也屬于前期綁定。除了static方法和final方法(private屬于final方法)之外的其他方法屬于后期綁定,運行時能判斷對象的類型進(jìn)行綁定[6,7].
4. 對象之間的交流
那么為了能讓對象之間有交互行為,能相互發(fā)送消息和接受消息,該如何做呢?一般來說有兩種方法:1)方法調(diào)用,A對象調(diào)用B對象的方法,這種方法最常用最直接,但是缺點是會導(dǎo)致A依賴于B。這個問題我們往往會通過面向接口編程在一定程度上消除這種依賴關(guān)系;2)事件消息模式,生產(chǎn)者-消費者模式,即采用觸發(fā)事件響應(yīng)事件的模式;通過這種方式,A對象就不是直接調(diào)用B對象的方法了,而是觸發(fā)一個事件,然后B對象去響應(yīng)這個事件,或者如果采用消息總線的方式的話,就是A對象通知消息總線發(fā)布某個事件,然后消息總線發(fā)布這個事件,然后B對象響應(yīng)這個事件[8].
參考資料
[1]博客: http://www.cnblogs.com/seesea...
[2]書籍: think in java (4 edition), page 1-4
[3]博客:http://book.51cto.com/art/201...
[4]博客:http://www.cnblogs.com/nuaalf...
[5]書籍: think in java (4 edition), page 11
[6]博客:http://www.cnblogs.com/NotOnl...
[7]博客:http://droidyue.com/blog/2014...
[8]博客:http://www.cnblogs.com/netfoc...
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/66041.html
摘要:第一章面向?qū)ο笮“资且婚T完全面向?qū)ο蟮木幊陶Z言嗯什么是面向過程什么又是面向?qū)ο竽卮罄性谖覀冋竭M(jìn)入學(xué)習(xí)這部分前,了解一下面向過程和面向?qū)ο筮@兩個概念,對于我們接下來的學(xué)習(xí)有很大的好處。這一部分我們會在面向?qū)ο髮W(xué)習(xí)結(jié)束后進(jìn)行系統(tǒng)的整理和總結(jié)。 showImg(https://segmentfault.com/img/remote/1460000019303357); 第一章 面向?qū)ο?小...
摘要:一學(xué)習(xí)資料今天入門了一門新的編程語言,主要對照清華大學(xué)出版社教材語言與面向?qū)ο蟪绦蛟O(shè)計,附帶在上寫了一個實例。重要的概念,如對象,屬性,方法等。因此需要在實操中強化操作技能,加深對概念的鞏固。輔以靈活引用已有的代碼庫,加速以及項目的進(jìn)展。 一、學(xué)習(xí)資料:今天入門了一門新的編程語言,主要對照清華大學(xué)出版社教材《Java 語言與面向?qū)ο蟪绦蛟O(shè)計》,附帶在eclipse 上寫了一個實例。 二...
摘要:首先,需要來理清一些基礎(chǔ)的計算機編程概念編程哲學(xué)與設(shè)計模式計算機編程理念源自于對現(xiàn)實抽象的哲學(xué)思考,面向?qū)ο缶幊淌瞧湟环N思維方式,與它并駕齊驅(qū)的是另外兩種思路過程式和函數(shù)式編程。 JavaScript 中的原型機制一直以來都被眾多開發(fā)者(包括本人)低估甚至忽視了,這是因為絕大多數(shù)人沒有想要深刻理解這個機制的內(nèi)涵,以及越來越多的開發(fā)者缺乏計算機編程相關(guān)的基礎(chǔ)知識。對于這樣的開發(fā)者來說 J...
摘要:下面我們來使用面向?qū)ο箢悎D這里就不再畫了首先面試題中所提到的我們都可以看成類,比如停車場是一個類吧,它里面的車位是一個類吧,攝像頭,屏幕。。。 以下是某場的一道面試題(大概): 1、一個停車場,車輛入場時,攝像頭記錄下車輛信息2、屏幕上顯示所接收的車輛的信息情況(車牌號)以及各層車位的車位余量3、停車場一共四層車位,其中的三層都為普通車位,還有一層為特殊車位(體現(xiàn)在停車計費價格上面的不...
閱讀 2936·2021-11-16 11:55
閱讀 2704·2021-09-29 09:34
閱讀 3621·2021-09-01 14:21
閱讀 3875·2019-08-29 12:36
閱讀 750·2019-08-26 10:55
閱讀 4125·2019-08-26 10:20
閱讀 1092·2019-08-23 18:19
閱讀 1254·2019-08-23 17:56