1. Overide尺碰,重寫
重寫一般是發(fā)生在子類繼承父類后记餐,某些父類方法不適應(yīng)子類的需求,而此時(shí)子類就重寫相同的方法粗恢,更加自己的需求柑晒,定義自己特定的行為。
簡單列子
public class Person {
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public void say() {
System.out.print("my name is "+name+"," + age + " years old this year");
}
}
public class Teacher extends Person{
public Teacher(String name, int age) {
super(name, age);
}
@Override
public void say() {
System.out.print("my name is " + super.name+"," + age + " years old this year," + "i'm a teacher");
}
}
子類Teacher繼承父類Person眷射,并重寫了say匙赞,重寫的時(shí)候,編譯器會幫你添加注解:override
凭迹。
1.1 輸入?yún)?shù)寬度
重載對輸入?yún)?shù)的寬度有限制罚屋,要求其必須等于父類的寬帶。對于上面的例子嗅绸,對Person增加一個(gè)方法:
/**
* 一下子吃超級多的東西
* 鍵值對:
* key - 食物名稱
* value - 食物數(shù)量
* @param map map
*/
public void eat(Map<String, ? extends Integer> map) {
Iterator<String> iterator = map.keySet().iterator();
while (iterator.hasNext()) {
String key = iterator.next();
System.out.println("eat " + key + ", " + map.get(key));
}
}
當(dāng)我們嘗試子類重載方法脾猛,并使其輸入?yún)?shù)小于父類的輸出參數(shù)(HashMap是Map的一個(gè)子集),編譯器提示報(bào)錯(cuò)
若此時(shí)我們把Override
去掉會發(fā)生什么鱼鸠?編譯通過猛拴,但當(dāng)傳入Map的對象時(shí)候羹铅,會直接調(diào)用父類方法,而當(dāng)傳入HashMap對象的時(shí)候愉昆,編譯器報(bào)錯(cuò)职员,提示,子類和父類皆有同名方法而參數(shù)類型也符合要球跛溉。當(dāng)我們把子類的方法改改:
public void eat(int a) {
System.out.print("Teacher, eat");
}
是可以成功焊切,且成功調(diào)用。
1.2 拋出異常寬度
重載對異常的拋出寬度有限制嗎芳室?還是同一個(gè)方法专肪,父類定義:
/**
* 一下子吃超級多的東西
* 鍵值對:
* key - 食物名稱
* value - 食物數(shù)量
* @param map map
*/
public void eat(Map<String, ? extends Integer> map) throws IOException{
Iterator<String> iterator = map.keySet().iterator();
while (iterator.hasNext()) {
String key = iterator.next();
System.out.println("eat " + key + ", " + map.get(key));
}
}
拋出一個(gè)異常IOException
,如果子類重載堪侯,拋出大于父類的異常Exception
:
編譯器報(bào)錯(cuò)嚎尤。那如果寬度小于父類的異常呢?
public class MyIOException extends IOException{
//定義一個(gè)繼承IOException的異常
}
@Override
public void eat(Map<String, ? extends Integer> map) throws MyIOException {
try {
super.eat(map);
} catch (IOException e) {
e.printStackTrace();
}
}
或者刪除異常
@Override
public void eat(Map<String, ? extends Integer> map) {
try {
super.eat(map);
} catch (IOException e) {
e.printStackTrace();
}
}
編譯伍宦,運(yùn)行成功芽死。不過如果想要調(diào)用super.eat(map)
,因?yàn)槠溆袙伋龅漠惓4瓮荩覍挾却笥谧宇惙椒ǖ?code>MyIOException关贵,所以需要先捕抓異常。
1.3 返回類型
跟輸入類型一樣滓玖,必須一致坪哄,不能修改。
1.4 方法訪問權(quán)限
一定不能做更嚴(yán)格的限制(可以降低限制)势篡,假如父類的方法聲明為protected
翩肌,則,子類可以重載其為public
但不能為private
禁悠。
2. Overload念祭,重載
重載發(fā)生在同一個(gè)類里面,名字相同碍侦,但是參數(shù)一定不同粱坤,返回值類型可以相同也可以不同。最常用到的是構(gòu)造函數(shù)瓷产。來看一些例子:
//1
protected void eat(Map<String, ? extends Integer> map) throws IOException{
System.out.println("eat Map");
}
//2
public void eat(HashMap map) {
System.out.println("eat HashMap");
}
//3
public void eat() {
System.out.println("eat null");
}
//4
public boolean eat(int a) {
System.out.println("eat a");
return true;
}
- 方法的參數(shù)一定要不同站玄,在次前提下,其他的隨意
- 方法返回值可以隨意變化
- 方法的拋出異常也是
- 方法的訪問權(quán)限也是
3. 總結(jié)
區(qū)別點(diǎn) | 重寫(Override) | 重載(Overload) |
---|---|---|
參數(shù) | 一定不能修改 | 必須不同 |
返回值 | 一定不能修改 | 隨意 |
拋出的異常 | 可以減少濒旦,刪除株旷,不能拋出寬度更大的異常 | 隨意 |
訪問權(quán)限 | 不能做更嚴(yán)格的限制 | 隨意 |
方法重載是一個(gè)類中定義了多個(gè)方法名相同,而他們的參數(shù)的數(shù)量不同或數(shù)量相同而類型和次序不同,則稱為方法的重載(Overloading)。
方法重寫是在子類存在方法與父類的方法的名字相同,而且參數(shù)的個(gè)數(shù)與類型一樣,返回值也一樣的方法,就稱為重寫(Overriding)。
方法重載是一個(gè)類的多態(tài)性表現(xiàn),而方法重寫是子類與父類的一種多態(tài)性表現(xiàn)晾剖。