基礎——面向對象

Java面向對象

一、類

  1. java程序的最基本單位
  2. 對一類有共同屬性和行爲事物的抽象叫做類

二、對象

1、定義

實實在在看得見摸得着的實體叫對象

  • 注:new出來的對象存在於內存的中,有默認值。比如Stringnullint0

代碼執行過程中內存原理分析

Demo

  • 類的定義
package com.student;

public class Student {
    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void show(){
        System.out.println("name=" + name + " , " +"age=" + age);
    }
}

2、單對象內存原理

  • 測試
package com.student;

public class StudentDemo {
    public static void main(String[] args) {
        Student s1 = new Student();
        s1.setName("小明");
        s1.setAge(18);
        s1.show();
    }
}

1、main方法在內存中進棧
在這裏插入圖片描述
執行構造方法,創建一個Student類得實例對象s1,於是在內存的堆空間開闢空間存儲s1成員變量,並初始化成員變量。構造方法出棧。
2、setName方法在內存中進棧
在這裏插入圖片描述
s1指向堆中的對象實例地址(假設是001),this指向的方法調用者實例,也就是s1.
方法執行結束出棧。
之後setAge方法同理。
4、執行show方法,show方法在內存
在這裏插入圖片描述

3、多對象內存原理

  • 測試
package com.student;

public class StudentDemo {
    public static void main(String[] args) {
        Student s1 = new Student();
        Student s2 = new Student();
        s1.setName("小明");
        s2.setName("小紅");
        s1.setAge(18);
        s2.setAge(20);
        s1.show();
        s2.show();
    }
}

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
後續方法調用同理,都是一個類方法執行,先進入內存棧區域,如果是賦值操作,那麼調用者對象便指向內存堆區域的真實地址,對成員變量進行賦值操作,在方法執行完畢之後,會將方法進行出棧,隨後後續方法接在內存中入棧,執行響應操作。

以demo的測試代碼爲例,接下來是Student的setAge方法入棧,調用者是s1,便指向s1在內存堆中的真實地址,對s1的age屬性進行賦值,之後setAge方法出棧,接着又是Student的setAge方法入棧,可這回調用者是s2,於是指向s2在內存堆中的真實地址,對s2的age屬性進行賦值,之後setAge方法出棧。接下來要執行的是Student類的show方法,兩個對象都有調用,依次是s1先調用show方法入棧,執行過後出棧,然後是s2調用show方法入棧,執行後出棧。最後main方法執行完畢,釋放s2,s1在內存中爲存儲成員變量開闢的空間,之後main方法出棧。到此爲止測試執行完畢。

4、對象指向相同地址的內存原理

  • 測試
package com.student;

public class StudentDemo {
    public static void main(String[] args) {
        Student s1 = new Student();
        s1.setName("小明");
        s1.setAge(18);
        Student s2 = s1;
        s2.setName("小紅");
        s2.setAge(20);
    }
}

在這裏插入圖片描述

三、類中的變量

區別 成員變量 局部變量
類中位置 類方法之外 類方法內或類方法聲明中
內存中位置
生命週期 因爲在堆中,所以隨着類得創建而創建,隨着類的銷燬而銷燬 因爲在棧中,所以隨着類方法的調用而產生,隨着方法的執行完畢而銷燬
初始化 有初始化 沒有初始化,必須要先創建,然後賦值,才能被使用

this指針

this修飾的變量指代成員變量

  • 作用:解決局部變量隱藏成員變量的問題。
  • 方法中this的指向:方法被哪個對象調用this就指向哪個對象。

private修飾符

屬於權限操作符,修飾類成員

  • 作用:保護類成員不被其他類使用,被private修飾的變量只能本類使用!

四、構造方法

  • 如果沒有定義構造方法,默認使用無參構造方法。
  • 如果定義了構造方法,系統將不再提供構造方法(建議都手動加上無參構造方法)

五、面向對象三大特徵:封裝、繼承、多態

(一)封裝

封裝是面向對象編程語言對客觀世界的模擬,客觀世界裏的成員變量都是隱藏在對象內部,外界是無法直接操作的

  • 原則:將類得某些信息通過private屬性隱藏在類內部,外界不能直接訪問,需要通過該類提供的public方法進行操作或訪問。
  • 好處:
  1. 通過方法來控制成員變量的操作,提高了代碼的安全性。
  2. 把代碼用方法進行封裝,提高了代碼的複用性。

(二)繼承

繼承就是有一堆的類,把這些類的共性方法抽取出來,作爲一個父類(也可叫做超類、基類),之後這些類就作爲它的子類,這些子類就能繼承父類中的所有非私有成員。

  • 注意事項:
  1. 子類繼承父類以後可以擁有父類的非私有成員
  2. 構造方法不能被繼承,私有成員不能被繼承,static修飾的成員不能被繼承
  • 格式:class 子類 extends 父類
  • 訪問成員變量:
  1. 不重名:如果訪問父類的對象,那隻能直接訪問父類的非私有成員變量。如果訪問子類的對象,那訪問的是子類和父類的非私有成員變量。
  2. 直接使用中,父類對象、本類對象重名:優先訪問=左邊的對象類型的變量,如果要對其進行區別可以使用this來特指本類對象、super特指父類對象
  3. 通過方法使用時,父類對象、本類對象、本類中的局部變量都重名:主要先看使用的是哪個類的方法,在方法中優先訪問本類的局部變量,訪問本類成員使用this指代,訪問父類的成員使用super指代。
  • 訪問成員方法
  1. 不重名:如果訪問的是父類的成員方法,那就只能訪問父類的成方法。如果訪問子類,那麼訪問的是子類的成員方法和父類的非私有成員方法。
  2. 重名:優先調用的同名方法主要看new的對象是什麼類型,如果要顯示進行區分最好使用thissuper來專門指代。
  • 方法的重寫
  1. 要求:重寫的方法必須和原來的方法一模一樣,雖然可以在方法的返回值可以是原來方法的子類型,但一般還是寫作一模一樣的類型。

  2. 使用場景:

    a. 子類想對父類方法進行增強,一般加一句 super.method();
    b. 父類方法是抽象的需要子類進行具體化。

面向對象中的抽象

在繼承中不得不談到抽象,因爲在現實世界中有很多東西的共性的十分抽象的,不能一句話說得清,比如人喫飯、狗喫飯、魚喫飯,他們具體的喫飯行爲大不相同,如果要把“喫飯”這個動作進行提取爲一個公共函數,那麼就必須使用抽象的方法,也就是說只聲明方法名,並聲明爲抽象方法,具體實現我們先不管,等定義具體的實現類時在進行行爲的定義。

  • 抽象方法:修飾符 abstract 返回類型 方法名(參數列表)

  • 抽象類: abstract class 類名

  • 注意事項:

  1. 將一類事物的共性方法抽取出來,但這個方法說不清道不明,就可以吧這個方法定義爲抽象方法。
  2. 抽象方法一定要在抽象類中。
  3. 抽象類中不一定有抽象方法。
  4. 抽象類可以有成員變量、構造方法、普通方法。
  5. 抽象類不能直接實例化。
  6. 抽象類的構造方法是爲了子實現類初始化時構造方法可以調用,用來初始化父抽象類中的成員變量
  7. 抽象類的子實現類必須重寫父類的全部抽象方法
  • 使用場景:一般作爲父類

(三)多態

現實世界中,一種事物有多種形態,比如我們自己,在學校是學生,在家是兒子。
一句話說多態就是:父類對象引用指向子類對象,調用父子共用的方法(子類重寫後的方法)。

  • 前提
  1. 有父子繼承關係(接口實現關係)
  2. 同名方法的重寫
  3. 父類引用指向子類對象
    父類 對象名 = new 子類()
  • 多態的使用步驟
  1. 定義類

  2. 定義子類繼承父類,重寫父類方法

  3. 父類引用指向子類對象–>父類名 對象名 = new 子類() ,調用重寫方法

    注意事項:
    1.必須有子父類繼承關係(接口,實現類的關係)
    2.必須又方法的重寫
    3.父類引用指向子類對象–>父類名父類名 對象名 = new 子類() ,調用重寫方法

  • 多態中的訪問特點
  1. 多態中如果出現子類和父類變量同名的訪問:看=左邊的類型,是什麼類型就訪問哪個類型的變量
  2. 多態中如果出現子類和父類方法同名的訪問:看new的對象是什麼類型,訪問的就是哪個類型的方法

如果子類中沒有變量或者方法就訪問父類

  • 多態和普通面向對象的優點和缺點
  • 普通面向對象:
    優點:可以訪問父類和本類的所有費私有方法
    缺點:擴展性差
  • 多態:
    優點:擴展性強,尤其在函數參數調用,重寫方法調用上
    缺點:不能通過指向子類的引用來使用子類的特有方法

對於多態的缺點,也可以通過向下轉型的方式解決。

  • 轉型
  1. 向上轉型:默認都是向上轉型,也就是父類對象引用指向子類對象
  2. 向下轉型:
//((Dog) animal).watchDoor();
Dog dog = (Dog) animal;
dog.watchDoor();

通過向下轉型就可以調用子類的特有方法

  1. 向下轉型可能會拋出異常:Exception in thread “main” java.lang.ClassCastException

對於這個異常可以通過關鍵字instanceof來解決,在轉型的時候進行判斷,判斷對象是否屬於某個類型。
使用方法:對象名 instanceof 類型

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章