super關鍵字的一些注意事項
- 子類在執行構造方法時,如果顯式使用super()顯式呼叫父類構造方法,則該呼叫必須放代碼塊在第一行
- super必須出現在子類的方法或者構造方法中
- 使用this()顯示呼叫構造方法,則該呼叫必須放在代碼塊第一行
- 由于第一條和第三條限制,super和this不能同時呼叫構造方法
class P1{
public P1(){
//this(); //不可以遞回呼叫構造方法
}
public P1(String str){
this();//可以呼叫多載的構造方法,該呼叫必須放在第一行
}
}
class S1 extends P1{
public S1(){
super();//顯式呼叫父類構造方法,該呼叫必須放在第一行
}
public S1(String str){
this();//無論呼叫自己的構造方法還是父類的構造方法,都要求在第一行,因此只能呼叫其中一個
System.out.println("constructor with parameter");
}
}
super 和 this的不同
- 代表的物件不同:
- this:本身呼叫者這個物件
- super:代表父類物件的參考
- 使用的前提不一樣:
- this沒有發生繼承也可以使用
- super只有在發生繼承時才可以使用,用來表示父類
- 構造方法不一樣:
- this() 呼叫本類的構造方法
- super() 呼叫父類的構造方法
方法重寫
方法重寫是多型的一個前提,需要在有繼承關系的前提下,由子類重寫父類的方法,并且存在幾點要求:
- 方法名必須相同
- 引數串列必須相同
- 重寫的方法修飾符范圍可以擴大: public>protected>default>private
- 拋出的例外范圍可以縮小,但不能擴大:ClassNotFoundException(小) ==> Exception(大)
- 回傳值型別可以縮小
class P2{
protected S1 run() throws Exception{
System.out.println("Father running!");
return new S1();
}
}
class S2 extends P2{
//修飾符范圍可以擴大,拋出例外范圍可以縮小
//子類方法與父類方法方法名、引數串列必須完全一致
public P1 run() throws ClassNotFoundException{
System.out.println("Son running!");
return new P1();//回傳值范圍可以縮小
}
}
多型注意事項
- 多型是方法的多型,屬性沒有多型
- 如果沒有繼承關系的類強制轉換,會導致ClassCastException型別轉換例外
- 多型的存在條件:繼承關系、方法重寫、父類參考指向子類物件, Father f1 = new Son();
因此,有一些方法是不能實作多型的: - static 方法不能實作多型,因為static方法是屬于類的,不屬于實體,當子類定義同名static方法時,會隱藏父類的同名方法,
- final 修飾的類和方法,因為final修飾的類為最終類,不能被繼承,斷子絕孫了,不能滿足繼承關系,自然也就無法實作多型;final修飾的方法不能被重寫,也不能實作多型
- private 修飾的方法,這類方法子類無法訪問,無法產生重寫,因此無法產生多型,
- 在實驗中,筆者注意到父類中 protected 修飾的方法在重寫后,只有在父類包路徑中可以實作多型,當實體范圍超出父類的包之后,該方法即只能被子類實體呼叫,父類參考指向的子類實體此時不能再呼叫該方法,
public class Test{
public static void mail(String args[]) throws Exception{
S2 stu = new S2();
stu.run();//無論在哪里都可以正常呼叫
P2 per = stu;//父類參考指向子類實體,此時發生多型
per.run();//只有當Test與父類P2在同一個包中時,父類參考per才可以訪問重寫的run()方法,
}
}
instanceof
instanceof的作用是判斷實體的型別
- 當型別由低向高轉化時,如子型別轉化為夫型別,直接使用父類參考指向子類實體即可,
- 當型別由高向低轉化時,需要進行強制型別轉換,這是因為子類實體一定是父類的實體,包含父類的所有域,而父類實體不一定時子型別的實體,包含的域可能更小,
- 子類轉換為父類時,可能丟失自己的方法,
class P3{
}
class S3 extends P3{
static void talk(){
System.out.println("Son talk sth");
}
public class Test{
public static void main(String[] args){
S3 son = new S3();
//此的S3的類方法talk()
son.talk();
P3 per = son;//直接使用父類應用指向子類物件,即完成了型別由低到高的轉換
//轉換成更高等級的父類后,子類中的talk不能被訪問了
//per.talk()//不能訪問
S3 son1 = (S3)per;//由父型別向子型別轉換則需要強制型別轉換
}
}
}
static
static在類加載時的一些作用
public class P4{
{
System.out.println("Anonymous code block!");
}
static {
System.out.println("Static anonymous code block!");
}
public P4(){
System.out.println("No parameter constructor!");
}
public static void main(String[] args){
P4 per1 = new P4();
System.out.println("==============");
P4 per2 = new P4();
}
}
執行結果如下:

可見靜態代碼塊在類加載時首先執行,且在類生命周期中只被執行一次,而匿名代碼塊則在構造方法之前執行,且每次實體化都會執行,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/549002.html
標籤:Java
上一篇:List介面和常用方法
