物件導向概念
所有操作基於物件進行操作實現
物件導向的三大特徵
封裝、繼承、多型
類:具有相同特徵和行為物體的統稱
在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()方法,獲取當前物件的型別