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