JAVA物件導向詳細總結

會碼程式碼的咕呱發表於2021-06-14

物件導向概念

  所有操作基於物件進行操作實現

物件導向的三大特徵

  封裝、繼承、多型

類:具有相同特徵和行為物體的統稱

在java中類的定義語法:

[修飾符]   class   類名{
  屬性;
  方法;
}


屬性和方法稱為成員、分別是成員屬性和成員方法

類的使用:
1.建立物件
結合關鍵字new, new 物件名(引數列表);

2.呼叫它的方法和屬性
物件名.屬性
物件名.方法(引數列表)


物件建立的詳細過程:

class Person{
        private String name;
        private int age;

        public Person{
            this.name=name;
            this.age=age;
        }
        {
            age=20;
        }
    }
class Main{
        public static void main(String[] args){
            Person person=new Person("XXX",18);
        }
    }

物件的具體建立過程:
1.在堆中開闢記憶體空間,JVM物件進行靜態初始化,就是給各個屬性賦予預設值

整數(byte、short、int、long):0
小數(double、float):0.0
字元(char):0/' '
布林值(boolean):false


2.JVM對物件進行動態初始化,就是執行< init >()方法,注意:IDEA 2018版本才顯示< init >()方法,其他版本不顯示

< init >()方法組成:成員屬性的賦值語句和構造程式碼塊從上往下組成
例如:{
age=20;
}

3.構造方法初始化:利用構造方法對屬性進行賦值

this:
出現的位置:出現在本類的構造方法中/成員方法中

作用:

1、表示當前物件,誰呼叫該方法,this就指代誰

2、可以呼叫本類中的構造方法,減少程式碼重複

區域性變數和成員變數的區別:

1.作用域:方法中可以直接使用成員變數(成員變數作用範圍整個類,區域性變數只能在方法中訪問)

2.記憶體分配:成員變數在堆中分配記憶體,區域性變數在棧中分配記憶體

3.成員變數:直接定義在類中 區域性變數:定義在方法中,包括方法引數

4.生命週期:區域性變數在方法執行完成就銷燬,成員變數根這個物件的銷燬而銷燬

5.有無預設值:JVM不會給區域性變數賦予預設值,JVM會給成員變數賦予預設值

如果一個類中區域性變數和成員變數同名,優先訪問區域性變數,可以用this區分區域性變數和成員變數
封裝的含義:定義類的過程

繼承:

為什麼要有繼承?

正面角度:擴充父類

反面角度:將子類中相同的程式碼抽象到父類中,提高程式碼的複用性,減少重複程式碼

繼承語法:

    public class 子類名 extends 父類名{

    }

方法的重寫:
子類重寫父類中的方法,除了方法體重寫之外,其他的和父類定義的一樣
方法的過載:
在同一個類中,方法名相同,引數列表不同(型別,順序,個數),和返回值相同

super:
1、可以在子類的構造方法中呼叫父類的構造方法,通過super呼叫父類中的構造方法
必須放在子類構造方法中的第一行,如果子類構造方法沒有呼叫父類的構造方法,預設呼叫無參構造
2、呼叫父類的構造方法給父類中定義的屬性賦值,或呼叫父類中的屬性和方法

修飾符:
訪問修飾符、static修飾符、final修飾符

訪問修飾符的作用:控制被修飾的內容(類、類的成員)在其他類中的訪問情況,具體參考baidu

一般結論:屬性使用private,方法使用public

在開發中,我們需要給類中每個屬性提供一個getter獲取方法和setter修改方法

訪問修飾符:public protected default private

static修飾符作用:控制被修飾的內容的載入時機

static修飾的成員就變為靜態成員,而且靜態成員不在屬於單個物件,而是屬於類

直接可以通過類名.屬性/方法名直接呼叫

類的載入過程:

JAVA中的類都是懶載入,需要用的時候才去載入

具體過程:

1、JVM將class載入到方法區(元空間)

2、JVM對類進行靜態初始化:給靜態屬性在方法區中的常量池開闢空間

3、JVM對類進行動態初始化:執行< cinit >()方法

< cinit >()方法組成:靜態屬性的賦值語句+靜態程式碼塊從上到下依次組成

類的初始化小細節:

如果父類沒有初始化,首先載入父類的.class檔案

然後再初始化本類

final修飾符:

final修飾類:類不可被繼承

final修飾方法:方法不可被重寫

final修飾變數:變數變常量

修飾成員變數,成員變數要再物件初始化階段或構造方法中完成賦值

修飾靜態變數:靜態變數必須在類的初始化階段完成賦值

抽象類:
抽象方法的定義語法:

        public abstract class ClassName{
            public abstract 返回值型別 方法名(引數列表);

        }

抽象可以含有抽象方法,但不能被例項化

一般的普通類不可以含有抽象方法,但含有抽象方法的一定是抽象類

抽象類的構造方法作用:

給子類物件在初始化的時候給父類中定義的屬性賦值

介面:比抽象類更加抽象,在介面中只能含有抽象方法(介面中方法的訪問修飾符預設是public abstract)和常量
定義語法:

[訪問修飾符] interface InterfaceName{
        public static final 資料型別 常量名=值;
        public abstract 返回值型別 方法名(引數列表);
    }

使用介面:

class ClassName implement InterfaceName{
            重寫介面中的方法
        }

多型:

向上轉型和向下轉型

向上轉型:父類型別/介面型別 物件名=子類型別的物件/子類型別物件的引用

父類引用指向子類的物件

通過物件名只能呼叫父類/介面中定義的方法,編譯看左邊,執行看右邊

class Person{
        String name;

        public void info(){

        }
    }

    class Chinese extends Person{
        @override
        public void info(){

        }
    }

    class Main{
        public static void main(String[] args){
            Person chinese=new Chinese();多型
        }
    }

向下轉型:
語法格式:子類型別 物件名=(子類型別)new 父類型別();

在編譯的時候,始終是正確的
但在執行的時候,需要檢測有邊物件的真正型別,只有型別和聲名型別一樣才能強轉成功

例:

class Animal{

    class Cat{

    }
    class Dog{

    }
    class Main{
            public static void main(String[] args){
                Animal animal=new Animal();
                Cat cat=(Cat)animal;
                Dog dog=(Dog)animal;//錯誤

                Animal01 animal01=new Dog();
                Dog dog=(Dog)animal01;//正確
            }
        }

補充:

instanceof:

A instanceof B: 判斷物件A是否是B類或B的子類的例項化物件

getClass()方法,獲取當前物件的型別

相關文章