更新時間:2022-04-29 10:00:44 來源:動力節點 瀏覽3349次
java多個類繼承的方法有哪些?動力節點小編來給大家舉例說明。
假設有三個java類,ClassA-ClassB-ClassC,ClassC在最底端。先看例子:
public class ClassA {undefined
public void fun1(){undefined
System.out.println(“A-fun1″);
}
public void fun2(){undefined
System.out.println(“A-fun2″);
}
public void fun3(){undefined
System.out.println(“A-fun3″);
}
public ClassA(){undefined
System.out.println(“A-ClassA”);
}
}
public class ClassB extends ClassA{undefined
public void fun1(){undefined
System.out.println(“B-fun1″);
}
public ClassB(){undefined
System.out.println(“B-ClassB”);
}
public ClassB(String str){undefined
System.out.println(“B-ClassB(String)”);
}
}
public class ClassC extends ClassB{undefined
public void fun1(){undefined
System.out.println(“C-fun1″);
}
public void fun2(){undefined
System.out.println(“C-fun2″);
System.out.println(“————-super.fun1()前————————”);
super.fun1();
System.out.println(“—————-super.fun1()后———————”);
}
public ClassC(){undefined
super(“aaa”);
System.out.println(“C-ClassC”);
}
public static void main(String[] agrs){undefined
ClassA c1 = new ClassC();
c1.fun1();
c1.fun2();
c1.fun3();
System.out.println(“————————————-”);
ClassB c2 = new ClassC();
c1.fun2();
c2.fun1();
}
}
輸出:
A-ClassA
B-ClassB(String)
C-ClassC
C-fun1
C-fun2
————-super.fun1()前————————
B-fun1
—————-super.fun1()后———————
A-fun3
————————————-
A-ClassA
B-ClassB(String)
C-ClassC
C-fun2
————-super.fun1()前————————
B-fun1
—————-super.fun1()后———————
C-fun1
c1這個對象,執行時的類型是ClassC。
首先說構造方法。如果不寫super(),相當于默認寫了個super(),如果new ClassC()會從最頂端的類開始初始化,依次調用
A-ClassA()
B-ClassB()
C-ClassC()
而此處,我們在ClassC中寫了個
super(“aaa”);
就會去調用B中的帶參數的構造方法,而不再調用無參的構造方法。所以,當new ClassC()時,
我們得到的結果是:
A-ClassA
B-ClassB(String)
C-ClassC
特別要注意的是,super()只能在構造方法中使用,而且只能在第一行使用。this()也是同樣的道理。
而我們在C的fun2()中調用了super.fun1();
則再一次調用了C的父類,也就是B的fun1(),輸出一個B-fun1。
再來說三個方法的覆蓋問題。
B覆蓋了fun1(),C覆蓋了fun1(),fun2()
也就是說,雖然B中沒有fun2(),而且C繼承了B,但C同樣可以覆蓋fun2()。
說明了,凡是整個繼承系統中有的方法,無論上一級類是否有,都可以覆蓋。
按照這種寫法
ClassA c1 = new ClassC();
B類中的方法,如果不是C類用了super.fun1(),是絕不可能調用到的。
也就是,如果不在C類的fun2()中寫super.fun1(),輸出結果應該是:
A-ClassA
B-ClassB(String)
C-ClassC
C-fun1
C-fun2
A-fun3
————————————-
A-ClassA
B-ClassB(String)
C-ClassC
C-fun2
C-fun1
而從ClassB c2 = new ClassC()來看,也不可能調用到C類中的方法,因為執行時的類型為C。
下面再看一個例子:
public class Class1 {undefined
int a = 1;
static int b = 2;
private int i = 1;
int j = 4;
{undefined
System.out.println(“normal—Class1–(a==”+a+”)–(b==”+b+”)”);
}
static{undefined
//System.out.println(“static—MClass1–”+a+”–”+b);//這里不認識非靜態變量
System.out.println(“static—Class1–(b==”+b+”)”);
}
public Class1(){undefined
System.out.println(“construct—Class1–(a==”+a+”)—(b==”+b+”)”);
System.out.println(“fun1—Class1–(this.i==”+this.i+”)”);
System.out.println(“fun1—Class1–(this.j==”+this.j+”)”);
this.fun1();
}
public void fun1(){undefined
System.out.println(“fun1—Class1–(i==”+i+”)”);
System.out.println(“fun1—Class1–(j==”+j+”)”);
}
}
public class Class2 extends Class1{undefined
int c = 1;
static int d = 2;
{undefined
System.out.println(“normal—Class2–(a==”+a+”)–(b==”+b+”)”);
System.out.println(“normal—Class2–(c==”+c+”)–(d==”+d+”)”);
}
static{undefined
//System.out.println(“static—MClass1–”+a+”–”+b);//這里不能調用非靜態變量
System.out.println(“static—Class2–(b==”+b+”)”);
System.out.println(“static—Class2–(d==”+d+”)”);
}
public Class2(){undefined
System.out.println(“construct—Class2–(a==”+a+”)—(b==”+b+”)”);
System.out.println(“construct—Class2–(c==”+c+”)—(d==”+d+”)”);
}
}
public class Class3 extends Class2{undefined
int e = 1;
static int f = 2;
private int i = 2;
int j = 3;
{undefined
System.out.println(“normal—Class3–(a==”+a+”)–(b==”+b+”)”);
System.out.println(“normal—Class3–(c==”+c+”)–(d==”+d+”)”);
System.out.println(“normal—Class3–(e==”+e+”)–(f==”+f+”)”);
}
static{undefined
//System.out.println(“static—MClass1–”+a+”–”+b);//這里不能調用非靜態變量
System.out.println(“static—Class3–(b==”+b+”)”);
System.out.println(“static—Class3–(d==”+d+”)”);
System.out.println(“static—Class3–(f==”+f+”)”);
}
public Class3(){undefined
System.out.println(“construct—Class3–(a==”+a+”)—(b==”+b+”)”);
System.out.println(“construct—Class3–(c==”+c+”)—(d==”+d+”)”);
System.out.println(“construct—Class3–(e==”+e+”)—(f==”+f+”)”);
i=222;
j=333;
}
public void fun1(){undefined
System.out.println(“fun1—Class3–(i==”+i+”)”);
System.out.println(“fun1—Class3–(j==”+j+”)”);
}
public static void main(String[] agrs){undefined
new Class3();
}
}
輸出結果:
static—Class1–(b==2)
static—Class2–(b==2)
static—Class2–(d==2)
static—Class3–(b==2)
static—Class3–(d==2)
static—Class3–(f==2)
normal—Class1–(a==1)–(b==2)
construct—Class1–(a==1)—(b==2)
fun1—Class1–(this.i==1)
fun1—Class1–(this.j==4)
fun1—Class3–(i==0)
fun1—Class3–(j==0)
normal—Class2–(a==1)–(b==2)
normal—Class2–(c==1)–(d==2)
construct—Class2–(a==1)—(b==2)
construct—Class2–(c==1)—(d==2)
normal—Class3–(a==1)–(b==2)
normal—Class3–(c==1)–(d==2)
normal—Class3–(e==1)–(f==2)
construct—Class3–(a==1)—(b==2)
construct—Class3–(c==1)—(d==2)
construct—Class3–(e==1)—(f==2)
1.類的初始化順序是:
(靜態變量、靜態初始化塊)>(變量、初始化塊)>構造器
而根據上面的輸出結果看出,三個類的靜態初始化塊執行完了,再依次是:
Class1的非靜態初始化塊
Class1的構造器
Class2的非靜態初始化塊
Class2的構造器
Class3的非靜態初始化塊
Class3的構造器
值得注意的是,靜態的方法和初始化塊中都不能直接調用非靜態變量!
2.寫了一個小插曲,如果Class1中的fun1()被Class2中的fun1()覆蓋,當Class1初始化(也就是調用Class1的構造器)時,
在Class1的構造器中調用this.fun1();會調到誰的?
兩個類都有兩個變量i、j,其中i是private
在Class1的構造器中調用this.i和this.j又會調到誰的?
記住一點,如果是調用方法,就看執行時的類型,如果是調用變量,就看編譯時的類型。
所以說,fun1()會調用到 Class3的,而i、j會調用到Class1的。
又由于,所有的變量和方法都會最先在內存中開辟空間,變量初始值默認為0或null,
例如定義了int i=3 相當于寫了先int i=0后面再寫i=3;
當Class1初始化時,Class3并沒有完成初始化,僅完在了int i=0這個步驟。
所以,在Class1初始化時調用Class3的fun1()輸出Class3的i和j的值均為0。
而在Class1的構造器中輸出i和j是屬于Class1的,在執行構造器前就已經完成了賦值
其實,這兒不寫this效果是一樣的。
以上就是關于“Java繼承多個類的例子”介紹,大家如果對此比較感興趣,想了解更多相關知識,不妨來關注一下動力節點的Java教程,里面的課程內容細致全面,通俗易懂,很適合小白學習,希望對大家的學習能夠有所幫助哦。
0基礎 0學費 15天面授
有基礎 直達就業
業余時間 高薪轉行
工作1~3年,加薪神器
工作3~5年,晉升架構
提交申請后,顧問老師會電話與您溝通安排學習