day08-fire
重寫/多態/類型轉換/其他
重寫
子類和父類擁有同名非靜態(static)方法時會發生重寫
父類的引用可以指向子類(和多態有關)
B類
package com.example.demo.oop.obj;
public class B {
public void a(){
System.out.println("B=>a()");
}
}
A類
package com.example.demo.oop.obj;
public class A extends B {
@override//注解:有功能的注釋
public void a(){
System.out.println("A=>a()");
}
}
Test 發生了重寫了
package com.example.demo.oop.obj;
public class Demo03 {
public void main(String[] args) {
A a=new A();
B b=new A();
a.a();//A=>a()
b.a();//A=>a()
}
}
static的進一步:類和對象
當A,B類里的同名方法是static的時候,這時候輸出結果就是A=>a()和B=>a(),這是因為static是類級別的,內存加載時會直接加載在堆空間。那么誰(A或B聲明)就會指向誰的方法,這時候就沒有發生重寫。只有當其方法為非靜態方法是,即對象級別的,那么new時就根據類名來確定方法。(和下面結合一下重寫理解可能會更好)
關于重寫和多態的問題
這里有個問題:父類的對象可以指向子類:
這是 Java 中多態(Polymorphism) 的核心體現之一,語法上稱為 “向上轉型(Upcasting
本質是 “子類是父類的一種特殊形式”(比如 “狗是動物的一種”),符合 “is-a” 關系 —— 既然 Dog 屬于 Animal 范疇,用 Animal 類型的變量來 “指代” Dog 對象,邏輯上完全成立
Q:A是B的子類,可以B a=new A(),但是不能A a =new B()對吧?就是可以說子像父,但是不能說父像子一樣?
A:核心邏輯就是 “is-a” 關系的單向性,父類引用可以指向子類對象,子類引用不能指向父類對象
關于調用成員限制:只能調用父類中聲明的成員
父類引用指向子類對象后,只能訪問父類中定義的方法 / 屬性,無法直接訪問子類特有的方法 / 屬性(除非通過 “向下轉型” 強制轉換類型)
簡言之:父類引用能 “裝” 子類對象,但只能用父類有的 “功能”。
final & static
final確保工具類/方法不被修改,而static確定了其屬于對象還是類級別
**summary: ** 重寫:
- 必須有繼承關系
- 方法名要一致
- 修飾符可以擴大,但是不能縮小 private<default<protected<public
- 重寫可能會拋出異常:范圍可以被縮小,但是不能擴大(精細化,錯誤有粗略到詳細)如:ClassNotFoundException --> Exception
為什么需要重寫:
- 從一般出發,需求沖突,即子類需要的方法或者其他父類不能滿足
快捷鍵:alt+ins可以重寫方法,構造方法等等
多態
[!IMPORTANT]
多態的核心:“編譯看左邊,運行看右邊”
在編譯階段,只看父類中是否有該方法,在運行時會調用實際指向的對象也就是子類,這就是多態的核心
對于子類A和父類B和基類Object
//一個對象的實際類型是一定的
//new A()
//new B()
//但是引用類型就不一定了,父類可以指向子類
//但是可以和(type)強制轉換,把父類的對象引用強制轉換為子類。這樣也可以調用子類的方法
/*
多態注意事項:
1.多態是方法的多態
2.類型轉換是需要有繼承關系的(轉換異常:ClassCastException)
3.存在:
繼承關系
方法重寫
父類的引用指向子類
**/
我的粗淺理解:從內存分配來說,在編譯時有標識身份的類來說明,編譯查看聲明類是否有該方法,沒有就直接報錯。在運行時,根據關鍵字new創建的空間來確定引用實際指向的方法。如果子類沒有就向去父類里面找。
方法加載一次,跟著類走,屬性跟著對象走,每個對象一份。只是非static的方法依賴于對象來調用而已
子類的加載依賴于父類的加載,先父后子嘛
instanceOf 和類型轉換
x instanceOf y:
- x和y有繼承關系才會編譯通過
- 真假值和x實例是不是y的子代
類型轉換:高轉低要強轉
-
父類的引用指向子類的對象
-
如果調用身份不符的方法的話就無法調用,所以需要類型轉換
-
B obj = new A()//A里有自己的方法go() ((A) obj).go()//這樣強轉身份就可以調用子類的方法了 -
子類轉換為父類可能會丟失一些方法
static
{
System.out.println("匿名代碼塊,用于復初值,先于構造方法,且沒new一個實例都會再運行一次")
}
static{
System.out.println("static代碼塊,于類同時,最先執行且只執行一次,因為是類級別的,然后才是main方法")
}
類加載和初始化
jvm先找到類的main方法,但是在執行main方法前必須對類進行初始化,包括了static代碼塊
只有初始化類后才執行main方法,這就是為什么先輸出static塊再輸出main的原因
靜態導入包 import static Java.lang.Math.max
??

浙公網安備 33010602011771號