Java物件導向(一)

早春的樹發表於2021-02-28

一、Java物件導向學習的三條主線

  1、Java類及類的成員。

    屬性、方法、構造器、程式碼塊、內部類。

  2、物件導向的三大特徵。

    封裝性、繼承性、多型性。

  3、其他關鍵字。

    this、super、static、final、abstract、interface、package、import等。

二、物件導向與程式導向的區別

  程式導向就是分析出解決問題所需要的步驟,然後用函式把這些步驟一步一步實現,使用的時候一個一個依次呼叫就可以了;物件導向是把構成問題事務分解成各個物件,建立物件的目的不是為了完成一個步驟,而是為了描敘某個事物在整個解決問題的步驟中的行為。

  可以拿生活中的例項來理解程式導向與物件導向,例如五子棋,程式導向的設計思路就是首先分析問題的步驟:1、開始遊戲,2、黑子先走,3、繪製畫面,4、判斷輸贏,5、輪到白子,6、繪製畫面,7、判斷輸贏,8、返回步驟2,9、輸出最後結果。把上面每個步驟用不同的方法來實現。

  如果是物件導向的設計思想來解決問題。物件導向的設計則是從另外的思路來解決問題。整個五子棋可以分為1、黑白雙方,這兩方的行為是一模一樣的,2、棋盤系統,負責繪製畫面,3、規則系統,負責判定諸如犯規、輸贏等。第一類物件(玩家物件)負責接受使用者輸入,並告知第二類物件(棋盤物件)棋子佈局的變化,棋盤物件接收到了棋子的變化就要負責在螢幕上面顯示出這種變化,同時利用第三類物件(規則系統)來對棋局進行判定。

  可以明顯地看出,物件導向是以功能來劃分問題,而不是步驟。同樣是繪製棋局,這樣的行為在程式導向的設計中分散在了多個步驟中,很可能出現不同的繪製版本,因為通常設計人員會考慮到實際情況進行各種各樣的簡化。而物件導向的設計中,繪圖只可能在棋盤物件中出現,從而保證了繪圖的統一。

  上述的內容是從網上查到的,覺得這個例子非常的生動形象,我就寫了下來,現在就應該理解了他倆的區別了吧,其實就是兩句話,物件導向就是高度實物抽象化、程式導向就是自頂向下的程式設計!

三、物件導向的兩個要素

  1、類:對一類事物的描述,是抽象的、概念上的定義。

  2、物件:是實際存在的該類事物的每個個體,因此也被稱為例項(instance)。

    >物件導向程式設計的重點是類的設計。

    >設計類就是設計類的成員。

四、類的設計

  1、設計類其實就是設計類的成員。

      常見的名稱:

      屬性 = 成員變數 = field = 域、欄位

      方法 = 成員方法 = 函式 = method

      建立類的物件 = 類的例項化 = 例項化類

  2、類和物件的使用(物件導向思想落地的實現)

    1. 建立類、設計類的成員
    2. 建立類的物件。
    3. 通過“物件.屬性”或“物件.方法”呼叫物件的結構。

  3、如果建立了一個類的多個物件,則每個物件都獨立擁有一套類的屬性(非static的)。如果我們修改一個物件的屬性a,不會影響其他物件同一屬性的值。

public class PersionTest {

    public static void main(String[] args) {
        // 建立Person類的物件
        Person p1 = new Person();

        // 呼叫物件的屬性、方法
        // 呼叫屬性 “物件名.屬性”
        p1.name = "Tom";
        p1.isMan = true;
        System.out.println(p1.name);
        System.out.println(p1.isMan);
        // 呼叫方法:“物件名.方法”
        p1.eat();
        p1.sleep();
        p1.talk("Chinese");
        
        //******************************
        Person p2 = new Person();
        System.out.println(p2.name);//null
        
        //****************************************
        //將P1變數儲存的物件地址值賦給p3,導致p1和p3指向了堆空間中的同一個物件實體。
        Person p3 = p1;
        System.out.println(p3.name);//Tom
        p3.age = 10;
        System.out.println(p1.age);//10
    }
}

/*---------------------------------測試類---------------------------------------*/
class Person {
    // 屬性
    String name;
    int age = 1;
    boolean isMan;

    // 方法
    public void eat() {
        System.out.println("人可以吃飯");
    }

    public void sleep() {
        System.out.println("人可以睡覺");
    }

    public void talk(String language) {
        System.out.println("人可以說話,使用的是" + language);
    }
}

五、物件的記憶體解析

    1. 堆(heap),此記憶體區域的唯一目的是存放物件例項,幾乎所有的物件例項都在這裡分配記憶體。這一點在Java虛擬機器規範中的描述是:所有的物件例項及陣列都要在堆上分配。
    1. 通常所說的棧(Stack),是指虛擬機器棧。虛擬機器棧用於儲存區域性變數等。區域性變數表存放了編譯期可知長度的各種基本資料型別(boolean、byte、char、short、int、float、double、long)、物件引用(reference型別、他不等同於物件本身,是物件在堆記憶體的首地址)。方法執行完自動釋放。
  1. 方法區
    1. 方法區(Method Area),用於儲存已被虛擬機器載入的類資訊、 常量、靜態變數、即時編譯器編譯後的程式碼等資料。

    4、解析圖:

                

六、屬性與區域性變數對比

    1、屬性(成員變數)與區域性變數

        相同點:

            1、定義變數的格式相同

            2、先宣告、後使用

            3、變數都有其對應的作用域

        不同點:

            1、在類中宣告的位置不同

                屬性:直接定義在一對{}內

                區域性變數:宣告在方法內、方法形參、程式碼塊內、構造器形參、構造器內部的變數。

            2、關於許可權修飾符的不同

                屬性:可以在宣告屬性時指明其許可權,使用許可權修飾符。

                    常用許可權修飾符:public、protected、卻省(預設)、private    ------->封裝性

                區域性變數:不可以使用許可權修飾符。

            3、預設初始化值的情況

                屬性:類的屬性根據其型別都有預設的初始化值。

                    整形(byte、short、int、long):0

                    浮點型(double、float):0.0

                    字元型(char):0(或‘\u0000’)

                    布林型(boolean):false

                區域性變數:沒有預設初始化

                    我們在呼叫區域性變數之前一定要顯示賦值

                    特別的:形參在呼叫時,我們賦值即可

            4、在記憶體中載入的位置不同。

                屬性:載入到堆空間(非static)

                區域性變數;載入到棧空間。

七、類中方法的宣告和使用

    方法:描述類應該具備的功能。

    例如:Math類:sqrt()、random()、........

       Scanner類:nextXxx()......

       Arrays類:sort()、binarySearch()、toString()、equals().......

    1、舉例:

       public void eat() {}            無返回值無形參

       public void sleep(int hour) {}         無返回值有形參

       public String getName() {}          有返回值無形參

       public String getNation(String nation) {}     有返回值有形參

    2、方法宣告方式:

      許可權修飾符   返回值型別    方法名 (形參列表){

          方法體

          }

    3、說明

      1、返回值型別:有返回值     無返回值

          (1)、如果方法有返回值,則必須在方法宣告時指定返回值型別。同時在方法結束時使用return關鍵字返回指定型別的資料 “return  資料;”。

               如果方法沒有返回值,則方法宣告時用void表示返回值型別。沒有返回值的方法中,就不需要使用return關鍵字。如果使用的話,只能“return;”表示結束此方法的執行。

          (2)、何時使用返回值?

              1、根據方法的功能需求設計相應的返回值。

      2、方法名:屬於識別符號,遵循識別符號的規則和規範,“見名知意”。

      3、形參列表:方法可以宣告0個,1個或者若干個形參。

          格式:許可權修飾符  返回值型別   方法名(資料型別1  形參1,資料型別2   形參2  ,資料型別3   形參3···········){}

      4、方法體:方法功能的體現。

      5、return關鍵字的使用:

        1、適用範圍:在方法體中。

        2、作用:1、結束方法。

              2、針對於有返回值型別的方法,使用“return  資料”返回所要的資料。

        3、注意點:return關鍵字後面不可以宣告執行語句。

      6、方法的使用:

        1、方法的使用中可以呼叫當前類的屬性或方法。

          方法A中又呼叫方法A:遞迴方法

        2、方法中不可以定義方法。

      7、方法的過載

        1、定義:在一個類中,允許存在一個以上的同命方法。只要他們的引數個數或引數型別不同即可。

              “兩同一不同”:同一個類相同方法名

                      引數列表不同:引數個數不同、引數型別不同。

        2、舉例:Arrays類中過載的sort()、binarySearch()........

        3、判斷是否過載:

          跟方法的許可權修飾符、返回值型別、形參變數名、方法體都沒有關係!

        4、在通過物件呼叫方法時,如何確定某一指定方法:

            方法名------------>形參列表

public class OverLoadTest {

    public void getSum(int i, int j) {
        System.out.println(1);
    }

    public void getSum(double i, double j) {
        System.out.println(2);
    }

    public void getSum(String s, int i) {

    }

    public void getSum(int i, String s) {

    }
    
//    *************錯誤示範******************

//    public int getSum(int i, int j) {
//        return 0;
//    }
    
//    public void getSum(int m, int n) {
//        
//    }
    
//    private void getSum(int i, int j) {
//        
//    }
    
}

 

八、物件陣列的記憶體解析

  1、引用型別的變數(物件),只可能儲存兩類值,null或地址值 (含變數的型別)。

  2、堆疊圖

    

 

 

 九、匿名物件的使用

  1、理解:通過new關鍵字建立物件,但沒有變數名接收物件的地址值。

  2、特徵:匿名物件只能呼叫一次。

  3、使用:如下。

public class InstanceTest {

    public static void main(String[] args) {
        Phone p = new Phone();
        p.sendEmail();//發郵件
        p.playGame();//玩遊戲
        
        
        //匿名物件
//        new Phone().sendEmail();//發郵件
//        new Phone().playGame();//玩遊戲
        
        new Phone().price = 1999;
        new Phone().showPrice();//手機價格為0.0
        
//        *********************************************************
        PhoneMall phoneMall = new PhoneMall();
        phoneMall.show(new Phone());//發郵件     玩遊戲
    }
    
}

class PhoneMall{
    public void show(Phone phone) {
        phone.sendEmail();
        phone.playGame();
    }
}

class Phone{
    double price;
    public void sendEmail() {
        System.out.println("發郵件");
    }
    
    public void playGame() {
        System.out.println("玩遊戲");
    }
    public void showPrice() {
        System.out.println("手機價格為"+price);
    }
    

}

 

相關文章