小記面向對象

来源:http://www.cnblogs.com/wangsen/archive/2016/01/04/5098038.html
-Advertisement-
Play Games

面向對象與面向過程:首先我們要明確一定:無論是面向對象還是面向過程他們都是解決同一個問題,只是方式不同而已。1.面向過程將程式看作一系列函數的集合,而面向對象將程式看作一種在程式中包含各種獨立而又互相調用的對象的集合。2.面向過程就是分析出解決問題所需的步驟,面向對象則是把問題中存在關鍵的事物抽取....


面向對象與面向過程:

首先我們要明確一定:
無論是面向對象還是面向過程他們都是解決同一個問題,只是方式不同而已。
1.面向過程將程式看作一系列函數的集合,而面向對象將程式看作一種在程式中包含各種獨立而又互相調用的對象的集合。

2.面向過程就是分析出解決問題所需的步驟,面向對象則是把問題中存在關鍵的事物抽取成對象。
抽取對象的目的在於將這些步驟分配到對應的對象中,由對象管理自己的行為。
比如:如何大象裝進冰箱?
面向過程:
為了把大象裝進冰箱,需要3個過程。
a.把冰箱門打開(得到打開門的冰箱)
b.把大象裝進去(打開門後,得到裡面裝著大象的冰箱)
c.把冰箱門關上(打開門、裝好大象後,獲得關好門的冰箱)
每個過程有一個階段性的目標,依次完成這些過程,就能把大象裝進冰箱。
面向對象:
為了把大象裝進冰箱,需要做三個動作(或者叫行為)。
每個動作有一個執行者,它就是對象。
a.冰箱,你給我把門打開
b.冰箱,你給我把大象裝進去(或者說,大象,你給我鑽到冰箱里去)
c.冰箱,你給我把門關上依次做這些動作,就能把大象裝進冰箱。
3.面向過程要關註每一個步驟的實現細節,關註度比較高,每次都要打開函數去理解每一步的含義。
面向對象不關註實現細節,只會關註這個步驟由哪個對象負責提供,對象對自己提供的服務負責。
4.面向對象編程是一種設計思想,OOP把對象作為程式的基本單元對象包含了屬性以及操作這些屬性的方法。

我認為兩者並不是對立的,而是兩者相互促進,oo思想能夠幫助我們以符合人類思維的方式進行思考問題,
面向過程的思想可以幫助我們在實現對象中提供的介面時保證邏輯順序的正確。

對象是什麼

面向對象是一種程式的設計思想,可以讓我們更符合人們的思維習慣。
面向對象的關鍵是在於“對象”,那什麼是對象呢?
相信大家一定聽過“一切皆對象”,這裡的對象指的是我們思考問題的目標物體,
比如:動物,地鐵,人,車這些都是我們關註的目標物體,也就是我們要思考的對象。
所有程式中存在的對象都是基於業務需求的環境下抽取的,否則將是無邊界的抽取,
它不僅能表示具體的事物,還能表示抽象的規則、計劃或事件。
所有說對象是面向對象的構建模塊,思考和設計的時候都是以對象為基本單元。

對象都有哪些構成

對象是屬性和行為集合的載體,從某種程度上說對象必須有屬性和對自身屬性操作的行為。
經常看到一些存放一堆函數沒有任何屬性的對象,嚴格意義上不能稱之為對象。
每一個對象都有一種實際的意義,賦予它的職責,對象只對屬於自己屬性和行為負責,也就我們
常說的“單一職責”。

對象之間通過消息進行交互

對象的存在必然是為了和其他對象進行交互,沒有任何交互的對象可以放棄啦。
比如:你踢貓,你是一個對象;你踢的那隻貓也是一個對象。你們兩個對象之間就是一種交互。
那這種交互又是如何發生的呢?在你踢貓這個例子中,你踢貓是你這個對象使用自身的踢這個行為,
這個行為作用到了貓這個對象身上。貓在被踢後,喵喵叫著跑離開你。
在這裡,貓這個對象的叫和跑這兩個行為得到了執行。
那試想,是誰執行了這兩個行為?顯然是貓,但這裡與其說是貓,還不如說是你在執行踢行為的過程中執行了貓的叫行為和跑行為。
不是麽?難道你踢貓不正是想讓貓走開,或者聽幾聲貓的慘叫來取樂?
所以假如你的名字叫Jason,你的貓叫Jack.那麼我們可以認為:Jason在踢方法內,調用了Jack的叫方法和跑方法。
用面向對象的記號記作:“Jason.踢(Jack)”調用了“Jack.叫()”和“Jack.跑()”。括弧中的Jack是Jason對象踢方法的參數,表示踢行為的作用對象。
用另外一種說法,我們認為:Jason在執行踢方法的過程中,給Jack發送了兩個消息以作為命令,Jack收到此兩消息後,執行了自己的方法。
這正是對象之間交互的實質所在,也即對象之間通過發送消息來進行交互。

類和對象的關係:

類是描述某些具有共性事物的一個抽象概念,它不是一個客觀存在的東西,它就是一個模板。
類可以定義對象
簡單說:類是對象的模板,對象是類的實例。
類的抽取過程是從眾多對象中提取出相似特征和動作進行封裝的,不是憑空捏造的,比如:
小明是一個學生,小花是一個學生,經過我們從這一個個對象中我們發現他們都有相同的屬性和行為,
這個時候就可以使用學生類進行承載。思考的過程是先有對象再有類,使用的時候現有類再創建對象。
需要強調一點:每個對象都擁有相同的方法,但各自的數據可能不同。

類都有哪些構成?

一個類通常有哪些元素構成,這些元素都有什麼存在價值,換句話我們可以通過這些元素可以乾什麼。
【類名】描述類的職責,知名達意
類名的好壞直接影響我們對這個類職責的定義,所以最好花點時間去琢磨一下類的命名。
【註釋】使用註釋說明方法,屬性,類職責
【屬性】用來表示對象狀態
【構造函數】 可以為創建對象提供多種形態的入口,可以初始化對象
構造函數是在對象初始化的時候使用的,通常某個對象在提供自己的對外服務的時候,必須讓其他對象傳遞相關的數據,
在構造函數中進行接受這些數據是經常的做法,如果某些數據是無關緊要的可以不用再對象創建時就提供的建議不要通過構造,
從某種意義上來說構造函數的用途就是為對象獲取整個生命周期重要的數據提供一個入口,對外表達一個意義: 你要想使用我(對象),就必須提供給我這些數據,否則我(對象)的服務是不能提供給你的。
比如:資料庫持久對象,在使用它提供操作數據服務之前必須要給它提供數據源連接的信息,不然是不可以使用的,具有強制性。
構造函數經常用來:
1.初始化本對象的所有屬性。
2.強制用戶類提供相關數據,並提供多種創建該對象的方法(構造函數重載)
3.也可以在類初始化的時候做其他的業務操作。

【訪問方法 setter】保證訪問屬性的安全,修改屬性保證只有一處
這也是面向對象又一特性"封裝"的體現,控制自身屬性的安全訪問。
【公共方法】 提供類對外的服務
提供公共方法也是類存在的重要職責,一個沒有任何對外服務的類可以放棄啦。
類內部提供方法的實現細節,而類的使用者不用關心具體謝姐。
提公共方法的命名一樣很重要,
【私有方法】 將不想用戶關心的實現,放到私有方法中。
【作用域】 控制屬性的訪問範圍。

怎麼創建一個合理的類

1.提供合適的構造函數。
2.讓類屬性的作用域儘可能小。
3.對類中的元素要合理添加上註釋,沒有任何註釋的類如果命名再不合理就會造成維護理解困難。
4.提供合適的對外介面,這個下麵有專門講。
5.設計的類必然是要和其他的類進行交互的,要麼是調用其他的服務,要麼本身提供服務,沒有這兩點的類可以幹掉啦。
6.要知道一個原則:類應該只對自己負責
自身狀態的變更:
比如:商品的狀態由上架,下架。如果要變更商品的狀態應該有商品自己去提供變更狀態的公共介面。
自身提供的服務:
比如:畫圖形,方形,圓形,星型它們內容應該是知道如何畫出自己的圖形。這就是對象負責自己的行為。
7.減少對象之間的依賴
相互依賴的比較少,也就是說一個類的修改不會對其他類產生影響,或者影響很小。
我們經常看到使用hibernate的對象之間關係維護都是對象中直接持有另外一個對象,或集合。
甚至將屬於另外一個類職責的行為放到了本類中。
這樣的設計會增加對象之間的依賴。

如何以面向對象的方式提供對外介面

這裡的對外介面指的是公共的函數。
一.設計介面要使用抽象思維,不體現實現的任何細節。
比如:做計程車去飛機場
計程車提供一個介面,叫做:去目的地就行啦
人只需要使用這個介面告訴計程車目的地就可以啦。不需要人關係有多遠,怎麼走。。。等細節信息。
這就要求我們在方法的命名上以及註釋上都必須保持抽象的思維用自然的語言去描述自己的函數。
二.為用戶提供最小的介面,用戶關註越小越好
1.以用戶需求為驅動編寫需要的介面,不要意淫要通過用例圖和流程圖來確定各個對象需要提供的介面。
比如:筆和筆記本,筆只想筆記本提供空白頁讓筆書寫,
但是筆記本覺得應該給筆提供一個畫好的格子頁面,這就是自作多情。
2.確定受眾用戶
註意: 有兩種身份關註介面,一種是最終用戶(互聯網用戶),一種是開發者之間的類介面。
互聯網用戶需要什麼服務我們就提供什麼介面,以此為驅動開發者,去理清這個服務的所有相關的業務,去抽象,
最終可能抽取出多個對象之間相互通信完成這個業務,其中對象之間的通信也叫介面,只不過這個介面是開發者關註的。
比如:各種service之間的介面它的受眾是開發者,module層中的module類就是互聯網用戶。
3.每個介面都要有明確的職責定義
確定的介面一定是只做一件事,單一的。
比如:下訂單是一個對外介面,你不能包含付錢的邏輯。
4.不要輕易修改你的公共介面(服務)
因為你不知道有多少類已經使用了你的這個介面,排查比較複雜

如何利用對象實現系統設計:

一、根據需求抽取出合適的類。
列舉需求或者產品原型中出現的所有名詞,根據名詞列表以及需求描述迭代分析找出真正的類(屬性和行為)
二、確定這些類的職責
1.從這個類需要負責的動作中抽象出這個類職責,能夠用一句話描述清楚。
2.找出這個類必須的屬性。
3.找出這個類必須的操作(只關註類的介面,不會關註實現)
三、確定這些類的關係
根據需求描述使用類去模擬實現的過程,找出對象之間的關係。
對象之間都有哪些關係可以參考另外一個博客:我對uml類圖的理解
四、利用建模語言:uml
使用uml的好處就是通過uml可以將你理解的對象關係向別人講解,也能幫助我們梳理和回顧。

對象的封裝:

封裝的本質:將不需要對外提供的內容都隱藏起來。
那我怎麼做才能算得上封裝呢?
1.將對象(類)中的屬性全部私有,並提供公有訪問該屬性的方法(就是咱們通常說的getter(),setter())
控制自身屬性對外界的訪問。【屬性的封裝】
2.只提供用戶關係的介面,隱藏實現的細節。【方法的封裝】
從上面就可以看出對象只封裝屬於自身內部的屬性和行為,所以她是獨立不依賴其他對象就可以實現自我管理。【好處】

對象之間的繼承:

繼承是指這樣一種能力:它可以使用現有類的所有功能,併在無需重新編寫原來的類的情況下對這些功能進行擴展。
在java中繼承的概念不僅限於"extend",其中我們經常使用的實現“implement”介面也是一種繼承。
子類和父類的關係一定是:屬於的關係即is-a
在java中繼承只能是單繼承不能多繼承但是可以多級繼承。
在java判斷對象是否存在is-a的關係可以使用關鍵字:instanceof判斷。
特別註意:
1.構造方法不能被繼承。
2.方法和屬性可以被繼承。
3.子類的構造方法隱式地調用父類的無參構造方法。
4.當父類沒有不帶參數的構造方法時,子類需要使用super關鍵字來顯示調用父類的構造方法。super指的是父類的引用。
5.super關鍵字必須是構造方法中的第一句。
6.生成子類對象時,Java預設地首先調用父類的不帶參數的構造方法,並執行該構造方法,生成父類的對象。
接下來才是調用子類的構造方法,生成子類的對象。(即是想要生成子類對象,必須先生成父類的對象,沒有父類的對象就沒有子類的對象)
繼承在實際的應用:
1.一般不會直接繼承一個已經編寫好的類,針對已有的類擴展我們都是採用組合的方式,對現有的舊介面進行包裝提供新的介面。
2.在模板模式中使用抽象類繼承介面,為真正的子類提供共有的預設實現。

對象的多態:

多態給我們帶來的好處是消除了類之間的耦合關係,使程式更容易擴展。
Java實現多態有三個必要條件:繼承(實現)、重寫、向上轉型。
繼承:在多態中必須存在有繼承關係的子類和父類以及實現關係的介面和實現類。
重寫:子類對父類中某些方法進行重新定義,在調用這些方法時就會調用子類的方法。
向上轉型:在多態中需要將子類的引用賦給父類對象,只有這樣該引用才能夠具備技能調用父類的方法和子類的方法。
只有滿足了上述三個條件,我們才能夠���同一個繼承結構中使用統一的邏輯實現代碼處理不同的對象,從而達到執行不同的行為。
先有繼承關係或者實現關係後才有多態。
其中,不同的對象可以執行相同的行為,但是他們都需要通過自己的實現方式來執行,這就要得益於向上轉型了。
我們需要知道:當子類重寫父類的方法被調用時,只有對象繼承鏈中的最末端的方法才會被調用。
多態的好處就是,當我們需要傳入Dog、Cat、Tortoise……時,我們只需要接收Animal類型就可以了,因為Dog、Cat、Tortoise……都是Animal類型,然後,按照Animal類型進行操作即可。由於Animal類型有run()方法,因此,傳入的任意類型,只要是Animal類或者子類,就會自動調用實際類型的run()方法,這就是多態。
實際應用:
1.依賴父類或者介面作為方法的參數。
2.依賴的對象如果有繼承關係我們就引用父類類型作為變數的數據類型。
方法重載也是一種多態:
可以實現對象對外提供多種形態(不同種類,不同數量的參數)的相同服務。
比如:訂單類有一個下訂單的介面叫create(),業務需求是:通過商品可以下訂單,通過某個活動也可以下定單;
這個時候我們對外暴露介面都是"下訂單",我們不想改變下訂單這個服務(介面)的定義,我們就可以通過方法的重載去實現。
create(商品) create(活動) 用戶可以根據自己的需求去選擇使用。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • D2前端技術論壇(Designer & Developer Frontend Technology Forum),簡稱D2。為國內前端開發者和網站設計師提供一個交流的機會,一起分享技術的樂趣,探討行業的發展,以技術會友。它是中國所有前端開發者的節日,包括前端設計師,前端開發工程師,和所有對前端技術....
  • 1. fill() arr.fill(value, [start], [end]) fill()方法向數組的開始位置到結束位置填充一個靜態值 參數: value: 要填充的值 start: 可選。開始位置,預設為0 end: 可選。結束位置,預設為length-1 返回: ...
  • Angular - React之爭Angular和React無疑是目前最受追捧的兩個前端框架,谷歌也發現Angular1.x不足的地方,開始開發2.0版本,臉書發現React的組件化和虛擬DOM非常好,也同時投資React Native。00.先比較Angular1.x與React這兩個沒什麼可比性...
  • weiphp後臺使用設置實現在用戶授權時候顯示公眾號的名字以及分享使用該服務號使用步驟1:在weiphp後臺打開公眾號管理-新增2:輸入公眾號名字,原始ID,微信號3:在這裡公眾號能查找到4: 輸入完成之後下一步,他會提供URL和token令牌.然後就要在微信公眾號後臺配置6輸入完成之後我,記錄下k...
  • Openfire和Strophejs網站功能變數名稱不同如何進行通信,這個問題總算解決,下麵是解決步驟。解決方案一:Chrome瀏覽器預設支持跨域訪問IE瀏覽器需要做配置:點擊IE瀏覽器的的“工具->Internet 選項->安全->自定義級別”將“其他”選項中的“通過域訪問數據源”選中為“啟用”或者“提示...
  • 題目:A message containing letters from A-Z is being encoded to numbers using the following mapping:'A' -> 1'B' -> 2...'Z' -> 26Given an encoded message ...
  • 1、什麼是 nutchNutch 是一個開源的、 Java 實現的搜索引擎。它提供了我們運行自己的搜 索引擎所需的全部工具。2、研究 nutch 的原因(1) 透明度: nutch 是開放源代碼的,因此任何人都可以查看他的排序演算法是如何工作的。商業的搜索引擎排序演算法都是保密的,我們無法知道為 什麼搜...
  • 與 WebServices 相關的 J2EE 技術稱為 JWS(Java WebServices),其中含有 JAX-WS、JAX-RS、JAXB、JAXR、SAAJ、StAX 等技術支持 SOAP 的是 JAX-WS,即 JSR 224,http://jcp.org/en/jsr/detail?i...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...