1. 程式人生 > 實用技巧 >科技愛好者週刊(第 128 期):這個社會是否正在變成“賽博朋克”?

科技愛好者週刊(第 128 期):這個社會是否正在變成“賽博朋克”?

面向物件

面向過程 & 面向物件

  • 面向過程思想

    • 步驟清晰簡單,第一步做什麼,第二步做什麼
    • 面對過程適合處理一些較為簡單的問題
  • 面向物件思想

    • 物以類聚,分類的思想模式,思考問題首先解決問題需要哪些分類,然後對這些分類進行單獨思考。最後,才對某個分類下的細節進行面向過程的思索
    • 面向物件適合處理複雜的問題,適合處理需要多人合作的問題
  • 對於描述複雜的事物,為了從巨集觀上把握、從整體上合理分析,我們需要使用面向物件的思路來分析整個系統。但具體到微操作,仍然需要面向過程的思路去處理

什麼是面向物件

  • 面向物件程式設計(Object-Oriented Program)
  • 面向物件程式設計的本質就是:以類的方式組織程式碼,以物件的組織(封裝)資料
  • 抽象
  • 三大特性:
    • 封裝
    • 繼承
    • 多型
  • 從認識論角度考慮,是先有物件後有類。物件,是具體的事物。類,是抽象的,是對物件的抽象
  • 從程式碼執行角度考慮,是先有類後有物件。類是物件的模版

類與物件的關係

  • 類是一種抽象的資料型別,它對某一類事物整體描述定義,但不能代表某一個具體事物
    • 動物,植物,手機,電腦
    • Person類、Pet類等等,這些類都是用來描述和定義某一類事物應該具有的屬性、特點、行為
  • 物件是抽象概念的具體例項
    • 張三就是人的一個具體例項
    • 能夠體現出特點,展現出功能的是具體的例項,而不是一個抽象概念

建立和初始化物件

  • 使用new關鍵字建立物件

  • 使用new關鍵字建立物件時,除了分配記憶體空間之外,還會對建立好的物件進行預設的初始化以及對類中構造器的呼叫

  • 類中的構造器(constructor)也稱為構造方法,是在進行建立物件時必須要呼叫的。並且構造器有以下兩個特點:

    1. 必須和類的名字相同
    2. 必須沒有返回型別,也不能寫void
  • new的本質就是在呼叫構造器

  • 構造器的作用:初始化物件的屬性

  • 注意:

    1. 定義有參構造之後,如果想使用無參構造,就要顯示的定義一個無參構造
    2. 快捷鍵:alt+insert;Mac:control+return

面向物件的三大特性之封裝

該露的露,該藏的藏

  • 程式設計要追求“”高內聚,低耦合“。高內聚就是類的內部資料操作細節自己完成,不想允許外部干涉;低耦合就是僅暴露少量的方法給外部使用

封裝(資料的)

  • 通常,應禁止直接訪問一個物件中的資料的直接表示,而應該通過操作介面來訪問,這稱為資訊隱藏
  • 屬性私有,get/set

面向物件的三大特性之繼承

  • 繼承的本質是對某一批類的抽象,從而實現對現實世界更好的建模

  • extends表子類是父類的擴充套件

  • Java中類只有單繼承,沒有多繼承

  • 繼承是類和類之間的關係。除此之外,類和類之間的關係還有依賴,組合,聚合等

  • 繼承關係的兩個類,一個是子類一個是父類,子類繼承父類,用關鍵詞extends表示

  • 子類和父類之前,從意義上講存在“is a“的關係

  • object類,在Java中,所有的類,都預設繼承object類

  • super(對比 this)

    1. 呼叫父類的構造方法,必須在構造方法第一行
    2. 必須只能出現在子類的方法或構造方法中
    3. super和this不能同時呼叫構造方法
    • vs this

      代表的物件不同

      • this:本身呼叫者這個物件
      • super:代表父類物件

      前提

      • this沒有繼承也可以使用
      • super只能在繼承條件下才可以使用

      構造方法

      • this(); 子類的構造方法
      • super(); 父類的構造方法

面向物件的三大特性之多型

方法重寫

  • 需要有繼承關係,子類重寫父類的方法

  • 方法名必須相同

  • 引數列表必須相同

  • 修飾符:範圍可以擴大,不能縮小:public > protected > default > private

  • 丟擲異常:可以被縮小,但不能擴大: ClassNotFoundException --> Exception(大)

  • 子類的方法必須要和父類的一致,方法體不同

  • 為什麼要重寫

    • 父類的功能子類不一定需要,或者不一定滿足需求
  • 不能重寫的情況:

    1. static 屬於類,不屬於例項
    2. final 常量
    3. private
  • control+return(Mac),override

多型

  • 動態編譯:型別:可擴充套件性

  • 即同一方法可以根據傳送物件的不同而採用多種不同的行為方式

  • 一個物件的實際型別是確定的,但可以指向物件的引用的型別可以有很多

  • 多型存在的條件

    1. 有繼承關係
    2. 子類重寫父類方法
    3. 父類引用指向子類物件
  • 多型是方法的多型,屬性沒有指向性

  • instanceof

    Student s1 = new Student();
    Person s2 = new Student();// 父類的引用指向子類
    Object s3 = new Student();
    
    //Object > String
    //Object > Person > Student
    //Object > Person > Teacher
    //System.out.println(x instanceof y);// 能否編譯通過取決於,x和y之間是否存在父子關係
    System.out.println(s3 instanceof Student); // true
    System.out.println(s3 instanceof Person); // true
    System.out.println(s3 instanceof Object); // true
    System.out.println(s3 instanceof Teacher); // false
    System.out.println(s3 instanceof String); // false
    System.out.println("=========================");
    
    System.out.println(s2 instanceof Student); // true
    System.out.println(s2 instanceof Person); // true
    System.out.println(s2 instanceof Object); // true
    System.out.println(s2 instanceof Teacher); // false
    System.out.println(s2 instanceof String); // 編譯報錯!
    
    System.out.println("=========================");
    
    System.out.println(s1 instanceof Student); // true
    System.out.println(s1 instanceof Person); // true
    System.out.println(s1 instanceof Object); // true
    System.out.println(s1 instanceof Teacher); // 編譯錯誤!
    System.out.println(s1 instanceof String); // 編譯報錯!
    
  • 型別轉換

    1. 把子類轉換為父類,向上轉型
    2. 把父類轉換為子類,向下轉型,強制轉換
    3. 方便方法的呼叫,減少重複的程式碼