面向物件概念

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

面向物件的三大特徵

  封裝、繼承、多型

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

在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()方法,獲取當前物件的型別