@Override是偽代碼,表示重寫(當(dāng)然不寫也可以),不過(guò)寫上有如下好處:
1、可以當(dāng)注釋用,方便閱讀;
2、編譯器可以給你驗(yàn)證@Override下面的方法名是否是你父類中所有的,如果沒(méi)有則報(bào)錯(cuò)。例如,你如果沒(méi)寫@Override,而你下面的方法名又寫錯(cuò)了,這時(shí)你的編譯器是可以編譯通過(guò)的,因?yàn)榫幾g器以為這個(gè)方法是你的子類中自己增加的方法。
舉例:在重寫父類的onCreate時(shí),在方法前面加上@Override 系統(tǒng)可以幫你檢查方法的正確性。
@Override
public void onCreate(Bundle savedInstanceState)
{…….}
這種寫法是正確的,如果你寫成:
@Override
public void oncreate(Bundle savedInstanceState)
{…….}
編譯器會(huì)報(bào)如下錯(cuò)誤:The method oncreate(Bundle) of type HelloWorld must override or implement a supertype method,以確保你正確重寫onCreate方法(因?yàn)閛ncreate應(yīng)該為onCreate)。而如果你不加@Override,則編譯器將不會(huì)檢測(cè)出錯(cuò)誤,而是會(huì)認(rèn)為你為子類定義了一個(gè)新方法:oncreate
java中的繼承,方法覆蓋(重寫)override與方法的重載overload的區(qū)別
方法的重寫(Overriding)和重載(Overloading)是Java多態(tài)性的不同表現(xiàn)。
重寫(Overriding)是父類與子類之間多態(tài)性的一種表現(xiàn),而重載(Overloading)是一個(gè)類中多態(tài)性的一種表現(xiàn)。
如果在子類中定義某方法與其父類有相同的名稱和參數(shù),我們說(shuō)該方法被重寫 (Overriding) 。子類的對(duì)象使用這個(gè)方法時(shí),將調(diào)用子類中的定義,對(duì)它而言,父類中的定義如同被屏蔽了。
如果在一個(gè)類中定義了多個(gè)同名的方法,它們或有不同的參數(shù)個(gè)數(shù)或有不同的參數(shù)類型或有不同的參數(shù)次序,則稱為方法的重載(Overloading)。不能通過(guò)訪問(wèn)權(quán)限、返回類型、拋出的異常進(jìn)行重載。
1. Override 特點(diǎn)
1、覆蓋的方法的標(biāo)志必須要和被覆蓋的方法的標(biāo)志完全匹配,才能達(dá)到覆蓋的效果;
2、覆蓋的方法的返回值必須和被覆蓋的方法的返回一致;
3、覆蓋的方法所拋出的異常必須和被覆蓋方法的所拋出的異常一致,或者是其子類;
4、方法被定義為final不能被重寫。
5、對(duì)于繼承來(lái)說(shuō),如果某一方法在父類中是訪問(wèn)權(quán)限是private,那么就不能在子類對(duì)其進(jìn)行重寫覆蓋,如果定義的話,也只是定義了一個(gè)新方法,而不會(huì)達(dá)到重寫覆蓋的效果。(通常存在于父類和子類之間。)
2.Overload 特點(diǎn)
1、在使用重載時(shí)只能通過(guò)不同的參數(shù)樣式。例如,不同的參數(shù)類型,不同的參數(shù)個(gè)數(shù),不同的參數(shù)順序(當(dāng)然,同一方法內(nèi)的幾個(gè)參數(shù)類型必須不一樣,例如可以是fun(int, float), 但是不能為fun(int, int));
2、不能通過(guò)訪問(wèn)權(quán)限、返回類型、拋出的異常進(jìn)行重載;
3、方法的異常類型和數(shù)目不會(huì)對(duì)重載造成影響;
4、重載事件通常發(fā)生在同一個(gè)類中,不同方法之間的現(xiàn)象。
5、存在于同一類中,但是只有虛方法和抽象方法才能被覆寫。
其具體實(shí)現(xiàn)機(jī)制:
overload是重載,重載是一種參數(shù)多態(tài)機(jī)制,即代碼通過(guò)參數(shù)的類型或個(gè)數(shù)不同而實(shí)現(xiàn)的多態(tài)機(jī)制。 是一種靜態(tài)的綁定機(jī)制(在編譯時(shí)已經(jīng)知道具體執(zhí)行的是哪個(gè)代碼段)。
override是重寫,重寫是一種動(dòng)態(tài)綁定的多態(tài)機(jī)制。即在父類和子類中同名元素(如成員函數(shù))有不同 的實(shí)現(xiàn)代碼。執(zhí)行的是哪個(gè)代碼是根據(jù)運(yùn)行時(shí)實(shí)際情況而定的。
Overrride實(shí)例 :
class A{ public int getVal(){ return(5); } } class B extends A{ public int getVal(){ return(10); } } public class override { public static void main(String[] args) { B b = new B(); A a= (A)b;//把 b 強(qiáng) 制轉(zhuǎn)換成A的類型 int x=a.getVal(); System.out.println(x); } }
結(jié)果:10
Overload實(shí)例:
public class Test{ public void save(int a){ } public void save(int a,int b){ } }
注意以下的實(shí)例:
class Father { public void foo(Object o) { System.out.println("Father.foo()"); } } class Son extends Father{ public void foo(String s) { System.out.println("Son.foo()"); } } public class Main { public static void main(String[] args) { Son son = new Son(); son.foo(new Object()); } }
結(jié)果:
Father.foo()
這里要注意的是,這里不叫方法重載,方法重載只能發(fā)生在同一個(gè)類中,雖然父子類中方法名相同,但是參數(shù)不同,原則上這也屬于兩個(gè)不同的方法。
short s1=1; s1=s1+1;有什么錯(cuò)?
short s1=1;s1+=1;有什么錯(cuò)?
對(duì)于前者,由于s1+1運(yùn)算時(shí)會(huì)自動(dòng)提升表達(dá)式的類型,所以結(jié)果是int類型,再賦值給short類型s1時(shí),編譯器會(huì)將報(bào)告需要強(qiáng)制轉(zhuǎn)換類型的錯(cuò)誤。
對(duì)于后者,由于+=是java語(yǔ)言規(guī)定的運(yùn)算符,java編譯器會(huì)對(duì)它進(jìn)行特殊處理,因此可以正常編譯。
補(bǔ)充:當(dāng)一個(gè)java算數(shù)表達(dá)式中包含多個(gè)基本類型的數(shù)據(jù)時(shí),整個(gè)算數(shù)表達(dá)式的類型將發(fā)生自動(dòng)類型提升。java定義的如下自動(dòng)提升規(guī)則:
1.所有的byte型、short型和char型將被提升為int型。
2.整個(gè)算數(shù)表達(dá)式的數(shù)據(jù)類型自動(dòng)提升到與表達(dá)式中最高等級(jí)操作數(shù)同樣的類型。操作數(shù)的等級(jí)排列如下圖所示,位于箭頭右邊類型的等級(jí)高于位于箭頭左邊類型的等級(jí)。
注:如果想把結(jié)果賦值給較小的類型,就必須使用類型轉(zhuǎn)換(既然把結(jié)果賦給了較小的類型,就可能出現(xiàn)信息丟失)。
構(gòu)造器Construct是否可被Override?
構(gòu)造器不能被繼承,因此不能被重寫Override,但可以被重載Override。
補(bǔ)充:繼承——子父類中的構(gòu)造函數(shù)的特點(diǎn):
在子類構(gòu)造對(duì)象時(shí)發(fā)現(xiàn),訪問(wèn)子類構(gòu)造函數(shù)時(shí),父類也運(yùn)行了。為什么呢?
原因是:在子類的構(gòu)造函數(shù)第一行有一個(gè)默認(rèn)的隱式語(yǔ)句:super();
super();//調(diào)用的是父類中的空參數(shù)的構(gòu)造函數(shù)。
子類實(shí)例化過(guò)程:子類中所有的構(gòu)造函數(shù)默認(rèn)都會(huì)訪問(wèn)父類中的空參數(shù)的構(gòu)造函數(shù)。
為什么子類實(shí)例化的時(shí)候要訪問(wèn)父類中的構(gòu)造函數(shù)呢?
因?yàn)樽宇惱^承父類,獲取了父類中的內(nèi)容(屬性),所以在使用父類內(nèi)容之前,要先看父類是如何對(duì)自己的內(nèi)容進(jìn)行初始化的。所以子類在構(gòu)造對(duì)象時(shí),必須訪問(wèn)父類中的構(gòu)造函數(shù)。為了完成這個(gè)必須的動(dòng)作,就在子類的構(gòu)造函數(shù)中加入了super()。
如果父類中沒(méi)有定義空參數(shù)構(gòu)造函數(shù),那么子類的構(gòu)造函數(shù)必須用super明確要調(diào)用父類中的哪個(gè)構(gòu)造函數(shù)。
注意:super語(yǔ)句必須要定義在子類構(gòu)造函數(shù)的第一行。因?yàn)楦割惖某跏蓟瘎?dòng)作要先完成。
通過(guò)super()初始化父類內(nèi)容時(shí),子類的成員變量并未顯示初始化,等super()父類初始化完畢后,才進(jìn)行子類成員的顯示初始化。
接口是否可繼承接口?抽象類是否可實(shí)現(xiàn)(implements)接口?抽象類是否可以繼承具體類?抽象類中是否可有靜態(tài)的main方法?
接口可以繼承接口
抽象類可以實(shí)現(xiàn)接口
抽象類可以繼承實(shí)體類,但和實(shí)體類的繼承一樣,也要求父類可繼承,并且擁有子類可以訪問(wèn)到的構(gòu)造器。
抽象類中可以有靜態(tài)的main方法。
其實(shí),抽象類和普通類的唯一區(qū)別就是不能創(chuàng)建實(shí)例對(duì)象和允許有abstract方法。
如對(duì)本文有疑問(wèn),請(qǐng)?zhí)峤坏浇涣髡搲?,廣大熱心網(wǎng)友會(huì)為你解答??! 點(diǎn)擊進(jìn)入論壇