java基础1--继承
java類的構造順序
public class test {public static void main(String[] args) {B b = new B("b"); //實體化一個B的對象b 使用了B(String )構造函數 B bb = new B("bb");//實體化了一個B的對象b } }class B {public B(String b1) {System.out.println(b1);}static {System.out.println("初始化靜態語句塊");} }執行結果:
初始化靜態語句塊 b bb可以看到初始化靜態語句塊輸出只有一次并且在第一個執行
在類內部,對于成員變量,如果在定義的時候沒有進行顯示的賦值初始化,則Java會保證類的每個成員變量都得到恰當的初始化:
1)對于 char、short、byte、int、long、float、double等基本數據類型的變量來說會默認初始化為0(boolean變量默認會被初始化為false);
2)對于引用類型的變量,會默認初始化為null。
當程序執行時,需要生成某個類的對象,Java執行引擎會先檢查是否加載了這個類,如果沒有加載,則先執行類的加載再生成對象,如果已經加載,則直接生成對象。
在類的加載過程中,類的static成員變量會被初始化,另外,如果類中有static語句塊,則會執行static語句塊。static成員變量和static語句塊的執行順序同代碼中的順序一致。記住,在Java中,類是按需加載,只有當需要用到這個類的時候,才會加載這個類,并且只會加載一次。在生成對象的過程中,會先初始化對象的成員變量,然后再執行構造器。也就是說類中的變量會在任何方法(包括構造器)調用之前得到初始化,即使變量散步于方法定義之間。
輸出結果:
初始化靜態語句塊 b 初始化靜態語句塊 bb結論:非靜態語句快被執行了兩次 注意這里去掉語句塊的大括號會報錯
public class test {public static void main(String[] args) {B b = new B();} }class B {public B() {System.out.println("b loaded");}C c = new C();}class C {public C() {System.out.println("c loaded");} }以上運行結果為:
c loaded b loadedc 在b之前生成 說明成員變量優先被初始化
下面是繼承相關的語法
class Person {public Person() {} }class Man extends Person {public Man() {} }類Man繼承于Person類,這樣一來的話,Person類稱為父類(基類),Man類稱為子類(導出類)。如果兩個類存在繼承關系,則子類會自動繼承父類的方法和變量,在子類中可以調用父類的方法和變量。在java中,只允許單繼承,也就是說 一個類最多只能顯示地繼承于一個父類。但是一個類卻可以被多個類繼承,也就是說一個類可以擁有多個子類。
1.子類繼承父類的成員變量
當子類繼承了某個類之后,便可以使用父類中的成員變量,但是并不是完全繼承父類的所有成員變量。具體的原則如下:
1)能夠繼承父類的public和protected成員變量;不能夠繼承父類的private成員變量;
2)對于父類的包訪問權限成員變量,如果子類和父類在同一個包下,則子類能夠繼承;否則,子類不能夠繼承;
3)對于子類可以繼承的父類成員變量,如果在子類中出現了同名稱的成員變量,則會發生隱藏現象,即子類的成員變量會屏蔽掉父類的同名成員變量。如果要在子類中訪問父類中同名成員變量,需要使用super關鍵字來進行引用。
2.子類繼承父類的方法
同樣地,子類也并不是完全繼承父類的所有方法。
1)能夠繼承父類的public和protected成員方法;不能夠繼承父類的private成員方法;
2)對于父類的包訪問權限成員方法,如果子類和父類在同一個包下,則子類能夠繼承;否則,子類不能夠繼承;
3)對于子類可以繼承的父類成員方法,如果在子類中出現了同名稱的成員方法,則稱為覆蓋,即子類的成員方法會覆蓋掉父類的同名成員方法。如果要在子類中訪問父類中同名成員方法,需要使用super關鍵字來進行引用。
注意:隱藏和覆蓋是不同的。隱藏是針對成員變量和靜態方法的,而覆蓋是針對普通方法的
構造器的繼承:
如果將B的無參構造其注釋去掉會報錯
當子類重新定義父類繼承的有參構造方法時 父類必須要有無參構造方法
如果父類的沒有無參構造方法則必須使用super
運行結果
B m loaded csuper()調用了父類的有參參構造方法:B(String b1);
如果使用super("c","d")則調用父類的方法B(String b1,String b2);
super.成員 的用法
要注意的是早使用super.之前要使用超類型的構造器
public class test {public static void main(String[] args) {C c = new C("c", "c");} }class B {String b = "10";/* public B(){System.out.println("b loaded");} */public B(String b1) {System.out.println("B " + b1 + " loaded");}public B(String b1, String b2) {System.out.println("B " + b1 + " " + b2 + " loaded");} }class C extends B {public C(String a) {super("m", "3");System.out.println(a);;}public C(String a1, String a2) {super("superb:" + " ");//當調用超類型構造器后可以在這里調用父類的成員變量System.out.println(super.b);} }一道題
public class test {public static void main(String[] args) {E e = new E();} }class C {public C(String cString) {System.out.println(cString + " constructor");} }class D {private C c = new C("c");public D() {System.out.println("D constructor");} }class E extends D {private D d = new D();public E() {System.out.println("E constructor");} }
輸出結果
c constructor D constructor c constructor D constructor E constructor如果將class E extends D{...}更改為class E{..}
public class test {public static void main(String[] args) {E e=new E();} }class C {public C(String cString) {System.out.println(cString + " constructor");} }class D {private C c = new C("c");public D() {System.out.println("D constructor");} }class E extends D {private D d = new D();public E() {System.out.println("E constructor");} }輸出結果為
c constructor
D constructor
E constructor
可以發現少了兩次輸出 因此該小題第一段代碼的實際的傳遞過程如下:
new E();//需要構造E 先構造E的父類D構造父類D要先構造父類的成員c
所以調用C();輸出了一次c constructor
繼續構造D 調用D的構造方法D(); 輸出D constructor
D構造結束后構造E
先構造E的成員d
d是D的對象 要實例化D 先構造D的成員c
new C("c");//調用了C的構造方法 輸出c constructor
//回到
D d=new D();//輸出constructor D 這時d也構造完畢
最后 調用E();方法構造e 結束
下面是驗證
public class test {public static void main(String[] args) {E e = new E();F f = new F();} }class C {public C(String cString) {System.out.println(cString + " constructor");} }class D {private C c = new C("c");public D() {System.out.println("D constructor");} }class E extends D {private D d = new D();public E() {System.out.println("E constructor");} }class F extends D {public F() {System.out.println("F constructor");} }輸出結果:
c constructor
D constructor
c constructor
D constructor
E constructor
c constructor
D constructor
F constructor
總結:先有父類后有子類 現有成員后有構造
每一次繼承前都會把父類的方法和成員構造一次
感謝作者海子 原文地址http://www.cnblogs.com/dolphin0520/p/3803432.html
轉載于:https://www.cnblogs.com/Salaku/p/5203937.html
總結
以上是生活随笔為你收集整理的java基础1--继承的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: The 5th Zhejiang Pro
- 下一篇: MAX_DEPTH, MAX_ROUTE