面向對象之封裝


面向對象

  • 面向對象編程(OOP —— Object Oriented Programing)

什么是面向過程、面向對象?

​ 面向過程與面向對象都是我們編程中編寫程序的一種思維方式

Ⅰ.面向過程的程序設計方式,是遇到一件事時,思考"我該怎么做",然后一步步實現的過程。

​ 例如:公司打掃衛生(擦玻璃、掃地、拖地、倒垃圾等),按照面向過程的程序設計方式會思考"打掃衛生我該怎么做,然后一件件的完成",最后把公司衛生打掃了個干凈

Ⅱ.面向對象的程序設計方式,是遇到一件事時,思考"我該讓誰來做",然后那個"誰"就是對象。他要怎么做這件事是他自己的事,反正最后一群對象合力能把事做好就行了

​ 例如:公司打掃衛生(擦玻璃、掃地、拖地、倒垃圾等),按照面向對象的程序設計方式會思考“我該讓誰來做,如小明擦玻璃,小麗掃地,小郭拖地,小李倒垃圾等”,他們合力把衛生打掃干凈

Ⅲ.買電腦(組裝機)

先使用面向過程說明買電腦這件事:

​ 我去網上查詢參數和報價,電腦城詢價,現場安裝和監督,抱電腦回家。在這整個過程中我參與了每一個細節,並且會感覺相當累。

使用面向對象說明買電腦這件事:

​ 首先找一個懂電腦硬件的人,讓他來幫我查詢參數和報價,並進行詢價和砍價,以及現場組裝和監督。而我不需要親歷親為,我只需要告訴這個人我的需求就可。

面向對象思維方式的好處

通過生活中的真實場景使用面向對象分析完之后,我們開始分析面向過程和面向對象的差異做出總結:

Ⅰ.面向對象思維方式是一種更加符合人們思考習慣的思想

Ⅱ.面向過程思維方式中更多體現的是執行者(自己做事情),面向對象中更多體現的是指揮着(指揮對象做事情)

Ⅲ.面向對象思維方式將復雜的問題簡單化

面向對象舉例

身邊的對象:

身邊的對象:

​ 超市:

​ 客戶:

​ 姓名:張浩

​ 身高:180cm

​ 體重:60kg

​ 操作 : 購物

​ 收營員:

​ 姓名:李明

​ 部門:財務部

​ 員工編號: 001

​ 操作:收銀、打印賬單、刷卡

對象的特征:

​ 屬性 —— 對象具有的各種特征

​ 每個對象的每個屬性都有特定值

1528959024044

​ 方法 —— 對象執行的操作

1528959250423

對象:用來描述客觀事物的一個實體,由一組屬性和方法構成

屬性(名詞)就這個對象是有什么,方法(動詞)就是這個對象可以做什么

我們來看:

1528959466713

​ 列出尼古拉斯·凱奇駕駛的這輛法拉利F360 Spider的屬性和方法

​ 屬性:

​ 品牌:法拉利

​ 顏色:黃色

​ 價格:380W

​ 型號:F360 Spider

​ 方法:

​ 發動

​ 加速

​ 停止

再來看:

1528959759847

​ 列出小狗的屬性與方法:

​ 屬性:

​ 顏色: 白色

​ 體重:7kg

​ 方法:

​ 叫

​ 跑

​ 吃

對象同時具有屬性與方法兩項特性

對象的屬性與方法通常被封裝到一起,用屬性與方法來共同體現事物的特性,二者相輔相成

1528960497778

說一說教師里面的對象,描述他們的屬性與方法

1528960673192

1528960737525

對象在代碼中的體現

在分析現實生活中的事物時發現,這些事物都有其具體的特點和功能,這些特點和功能就組成了這個特殊的事物

我們來描述一輛小汽車:

​ 分析:

​ 事物的特點(屬性):

​ 顏色

​ 輪胎個數

​ 事物的功能:

​ 運行

​ 發現:事物其實就是由特點(屬性)和行為(功能)組成的。

​ 可以簡單的理解:屬性就是數值,其實就是變量;行為就是功能,就是方法。

​ 小汽車{

​ 顏色;

​ 輪胎個數;

​ 運行(){};

​ }

通過計算機語言java開描述這個事物

​ 定義類的格式:


​ 汽車類:

  public class car{

    String color;//顏色

    int number;//輪胎個數

    //行駛    

    public void run(){

        System.out.println("一輛顏色為"+color+"輪子數為"+number+"的車行駛在蜿蜒的馬路上");

    }

  }

通過代碼的描述,知道類的真正意義就是在描述事物。屬性和功能統稱為事物中的成員。

​ 事物的成員分為兩種: 成員屬性和成員功能。

​ 成員屬性在代碼中體現就是成員變量

​ 成員功能在代碼中體現就是成員方法

​ 把寫好的代碼測試一下。需要一個獨立運行類

​ 測試類:

  public class CarDemo(){

  

   /* * 測試:Car類中的run方法 */ // 1.創建Car對象,給對象起個名字

   public staic void main(String[] args){

   Car  c = new Car();

     // c是類的類型變量,c指向了一個具體的Car類型的對象 // 通過已有的對象調用該對象的功能。格式:對象.對象成員; //可以給對象的屬性賦值
  
     c.color = "blue";   c.number = 4;   c.run();

 }

}

類和對象的區別

面向對象的編程思想力圖在程序中對事物的描述與該事物在現實中的形態保持一致。為了做到這一點,面向對象的思想中提出兩個概念,即類和對象。其中,類是對某一類事物的抽象描述,而對象用於表示現實中該類事物的個體

如下圖所示:

 

將玩具模型看作是一個類,將一個個玩具看作對象,從玩具模型和玩具之間的關系便可以看出類與對象之間的關系。類用於描述多個對象的共同特征,它是對象的模板。對象用於描述現實中的個體,它是類的實例。從上圖中可以明顯看出對象是根據類創建的,並且一個類可以對應多個對象,接下來分別講解什么是類和對象

創建對象使用關鍵字 new

局部變量與成員變量

區別一:定義的位置不同

​ 定義在類中的變量是成員變量

​ 定義在方法中或者{}語句里面的變量是局部變量

區別二:在內存中的位置不同

​ 成員變量存儲在對內存的對象中

​ 局部變量存儲在棧內存的方法中

區別三:聲明周期不同

​ 成員變量隨着對象的出現而出現在堆中,隨着對象的消失而從堆中消失

​ 局部變量隨着方法的運行而出現在棧中,隨着方法的彈棧而消失

區別四:初始化不同

​ 成員變量因為在堆內存中,所有默認的初始化值

​ 局部變量沒有默認的初始化值,必須手動的給其賦值才可以使用


面向對象三大特性

  • 封裝

    • 只隱藏對象的屬性和實現細節,僅對外提供公共訪問方式
    • 好處
      • 將變化隔離、便於使用、提高復用性、提高安全性
    • 原則
      • 將不需要對外提供的內容隱藏起來;把屬性隱藏,提供公共方法對其訪問
  • 繼承

    • 子類自動擁有父類非私有的屬性與方法
    • 提高代碼復用性;繼承是多態的前提
  • 多態

    • 類的多種形態。是父類或接口定義的引用變量可以指向子類或具體實現類的實例對象
    • 好處
      • 提高了程序的擴展性
    • 弊端
      • 當父類引用指向子類對象時,雖提高了擴展性,但只能訪問父類中具備的方法,不可訪問子類中的方法;即訪問的局限性
    • 前提
      • 實現或繼承關系;覆寫父類方法

面向對象設計原則

  • 開 : 開閉原則)
  • 口 : 接口隔離原則
  • 合 : 組合|聚合原則
  • 里 : 里式替換原則
  • 最 : 最少知識原則(迪米特法則)
  • 單 : 單一職責原則
  • 依 : 依賴倒置原則

解釋


TDD(Test Driver Devolepment ) 測試驅動編程

  • TDD 測試驅動編程, 編程方法學,編程思想
    * DDD(Domain-driven design) 領域驅動設計 優劣: 保證了代碼質量,測試的覆蓋率高。開發效率低 測試: 本身也是一套完整的學科 單元測試 白盒測試:能看到源碼 黑盒測試:沒有源碼,功能測試 灰盒測試:基於白盒與黑盒之間的測試,通過一些表征性的現象、事件、標志來判斷內部的運行狀態 壓力測試: 並發數的問題,能承載多少並發 疲勞強度測試: 長期穩定運行,72小時 7冒煙測試: 對某一個功能瘋狂的測試,主要流程(支付環節) 集成測試: 完整功能測試,最重要測試整體業務流程 回歸測試: 增加一個功能(重新測試) 自動化測試: 編碼,場景設計(模擬場景,設計編碼) 代碼評審: 看有沒有留后門

 JUnit簡介

  

  • JUnit 是用於編寫和運行可重復的自動化測試的開源測試框架,這樣可以保證我們的代碼按預期工作。JUnit 可廣泛用於工業和作為支架(從命令行)或IDE(如 IDEA)內單獨的 Java 程序

  • JUnit 提供

    • 斷言測試預期結果
    • 測試功能共享通用的測試數據
    • 測試套件輕松地組織和運行測試
    • 圖形和文本測試運行
  • JUnit 用於測試

    • 整個對象

    • 對象的一部分 - 交互的方法或一些方法

    • 幾個對象之間的互動(交互)


  • JUnit 特點

    • JUnit 是用於編寫和運行測試的開源框架

    • 提供了注釋,以確定測試方法

    • 提供斷言測試預期結果

    • 提供了測試運行的運行測試

    • JUnit 測試讓您可以更快地編寫代碼,提高質量

    • JUnit 是優雅簡潔。它是不那么復雜以及不需要花費太多的時間

    • JUnit 測試可以自動運行,檢查自己的結果,並提供即時反饋。沒有必要通過測試結果報告來手動梳理

    • JUnit 測試可以組織成測試套件包含測試案例,甚至其他測試套件

    • Junit 顯示測試進度的,如果測試是沒有問題條形是綠色的,測試失敗則會變成紅色


  • JUnit 注解
注解 描述
@Test public void method() 測試注釋指示該公共無效方法它所附着可以作為一個測試用例。
@Before public void method() Before 注釋表示,該方法必須在類中的每個測試之前執行,以便執行測試某些必要的先決條件
@BeforeClass public static void method() BeforeClass 注釋指出這是附着在靜態方法必須執行一次並在類的所有測試之前。發生這種情況時一般是測試計算共享配置方法(如連接到數據庫)。
@After public void method() After 注釋指示,該方法在執行每項測試后執行(如執行每一個測試后重置某些變量,刪除臨時變量等)
@AfterClass public static void method() 當需要執行所有的測試在 JUnit 測試用例類后執行,AfterClass 注解可以使用以清理建立方法,(從數據庫如斷開連接)。注意:附有此批注(類似於 BeforeClass)的方法必須定義為靜態。
@Ignore public static void method() 當想暫時禁用特定的測試執行可以使用忽略注釋。每個被注解為 @Ignore 的方法將不被執行。

  • JUnit 斷言

  • 什么是斷言

    • 斷言是編程術語,表示為一些布爾表達式,程序員相信在程序中的某個特定點該表達式值為真,可以在任何時候啟用和禁用斷言驗證,因此可以在測試時啟用斷言而在部署時禁用斷言。同樣,程序投入運行后,最終用戶在遇到問題時可以重新啟用斷言。

    • 使用斷言可以創建更穩定、品質更好且 不易於出錯的代碼。當需要在一個值為 false 時中斷當前操作的話,可以使用斷言。單元測試必須使用斷言(Junit/JunitX)。

  • 常用斷言方法

斷言 描述
void assertEquals([String message], expected value, actual value) 斷言兩個值相等。值可能是類型有 int, short, long, byte, char or java.lang.Object. 第一個參數是一個可選的字符串消息
void assertTrue([String message], boolean condition) 斷言一個條件為真
void assertFalse([String message],boolean condition) 斷言一個條件為假
void assertNotNull([String message], java.lang.Object object) 斷言一個對象不為空(null)
void assertNull([String message], java.lang.Object object) 斷言一個對象為空(null)
void assertSame([String message], java.lang.Object expected, java.lang.Object actual) 斷言,兩個對象引用相同的對象
void assertNotSame([String message], java.lang.Object unexpected, java.lang.Object actual) 斷言,兩個對象不是引用同一個對象
void assertArrayEquals([String message], expectedArray, resultArray) 斷言預期數組和結果數組相等。數組的類型可能是 int, long, short, char, byte or java.lang.Object.

 

 /** * 測試斷言 */ @Test public void testAssert() { String obj1 = "junit"; String obj2 = "junit"; String obj3 = "test"; String obj4 = "test"; String obj5 = null; int var1 = 1; int var2 = 2; int[] arithmetic1 = {1, 2, 3}; int[] arithmetic2 = {1, 2, 3}; assertEquals(obj1, obj2); assertSame(obj3, obj4); assertNotSame(obj2, obj4); assertNotNull(obj1); assertNull(obj5); assertTrue("為真", var1 == var2); assertArrayEquals(arithmetic1, arithmetic2); } 

封裝

封裝有兩層含義:

​ 1.對功能的封裝,比如我們的方法,方法就是一個功能的實現

​ 2.對數據的封裝,就比如手機的價格、屏幕等

封裝的表現:

​ 1.方法就是一個最基本的封裝

​ 2.類其實就是一個封裝體

封裝的好處:

​ 1.提高了代碼的復用性

​ 2.影藏實現細節,對外提供可以訪問的方法。便於使用者去使用,這是核心之一,也就是理解為封裝的概念。

​ 3.提高了安全性

  • 封裝舉例:

    • 比如人:
      • 屬性:
        • 姓名
        • 年齡
      • 方法:
        • 吃飯

不私有化屬性:

  public class Person{

    String name;

    int age;

    public void eat(){

      System.out.println(name+"在吃飯")

  }    

}

  public class PersonDemo(){

  

public static void main(){ //創建Person的對象 Person person = new Person(); person.name="人妖"; person.age = "18"; p.eat(); }

}

 

通過上述代碼,我們用Java代碼把Person描述清楚了,但有個嚴重的問題,就是Person中的屬性是可以用直接訪問的。

怎么才能不讓直接訪問呢?

​ 需要使用java中的一個關鍵字private(私有,權限修飾符)。只要將Person的屬性和行為私有起來,這樣就無法直接訪問。

私有化屬性:

public class Person{ private String name; private int age; /* 提供set與get方法 */ public void setName(String name){ this.name = name;//this代表本類對象 } public String getName(){ return this.name; } public void setAge(int age){ this.age = age; } public int getAge(){ return this.age; } public void eat(){ System.out.println(name + "在吃飯"); } } public class PersonDemo{ public static void main(String[] args){ Person person = new Person(); //現在 person.name = "人妖";是行不通的,那我們要腫么辦呢? person.setName("小則"); } }

總結:

​ 類中不需要對外提供的內容都私有化,包括屬性和方法。

​ 以后再描述事物,屬性都私有化,並提供setXxx getXxx方法對其進行訪問。

注意:私有僅僅是封裝的體現形式而已

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM