Java——重载和重写
前言
在程序設(shè)計中經(jīng)常會遇到對對方法的重載或者重寫,下面將介紹重載和重寫。
重載(Overloade)
重載出現(xiàn)的原因
任何程序設(shè)計語言都具備的一項重要特性就是對名字的運用。當(dāng)創(chuàng)建一個對象時,就給對象的存儲空間取了一個名字。方法名就是給某個動作取的名字。通過使用名字,我們可以引用所有對象和方法。名字起的好可以使程序更易于理解和修改。
在大多數(shù)程序設(shè)計語言中要求為每個方法提供唯一的標識符。不能使用print()的函數(shù)顯示了整數(shù)之后,又用一個名為print()的函數(shù)顯示浮點數(shù)。即,每個函數(shù)(方法)都要有唯一的名稱。這是迫使出現(xiàn)重載方法的理由之一。若是print()函數(shù)可以被重載了,那么就既可以輸出整數(shù)也可以輸出浮點數(shù)。或者又可以舉例:我們要計算兩個整數(shù)相加,我們可以設(shè)計方法為int add(int a, int b)。調(diào)用add(10,10)我們就可以知道是計算兩個整數(shù)相加。此時,我們又想計算兩個浮點數(shù)相加,因為add見名知意所以我們繼續(xù)使用這個名字,那么就需要方法double add(double a, double c)。于是,add()方法就被重載了。
在Java(和C++)里,構(gòu)造器是強制重載方法出現(xiàn)的另一個原因。構(gòu)造器的名字由類名決定,那么就只能有一個構(gòu)造器。但是,又想使用多種方式創(chuàng)建對象又該怎么辦呢?那么就只有重載構(gòu)造器,使得同名不同參的構(gòu)造器同時存在。
重載的規(guī)則
方法重載是在一個類里面,方法名相同,而參數(shù)不同,對返回值沒有強制要求可以相同也可以不同。方法重載需要注意一下幾點:
- 被重載的方法必須改變參數(shù)列表(參數(shù)個數(shù)或者類型不一樣)
- 被重載的方法介意改變返回類型和訪問修飾符
- 被重載的方法可以聲明新的或者更廣的檢查異常
- 方法能夠在同一個類中或者在一個子類中被重載
- 不可以返回值類型作為分區(qū)重載函數(shù)的標準
區(qū)分重載方法
每個重載的方法都有獨一無二的參數(shù)類型列表。所以在區(qū)分重載方法時,只能以類名和方法的形參列表作為標準。
那為什么不能使用方法的返回值來區(qū)分呢?
比如下面兩個方法,雖然它們有相同的名字和形式參數(shù),但是卻很容易區(qū)分它們
void f(){} int f() {return 1;}只要編譯器可以根據(jù)語境明確判斷出語義,比如在int x = f()中,那么的確可以根據(jù)此區(qū)分方法。不過,有時你并不關(guān)心方法的返回值,你想要的是方法調(diào)用的其他效果,這時你可能會調(diào)用方法而忽略返回值。所以,向下面這樣的調(diào)用方法:
f();此時Java該怎樣判斷調(diào)用的是哪個方法呢?別人也無法理解這個代碼的含義。因此,依據(jù)方法的返回值來區(qū)分重載方法是行不通的。
重寫(Override)
重寫出現(xiàn)的原因
先看一個例子
class Animal{public void printWhoIAm(){System.out.println("Animal")} } public class Dog extends Animal{public static void main(String args[]){Dog dog = new Dog();dog.printWhoIAm();} } /* output: Animal */當(dāng)dog調(diào)用printWhoIAm()方法時,其實希望的是輸出“dog”,而不是Animal。要實現(xiàn)輸出“Dog”,想到了重載,可是重載要求被重載的方法具有不同的形參列表。這個方法不得行。dog調(diào)用的printWhoIAm()是父類中的,在子類中若是可以重寫這個方法,那么就可以實現(xiàn)目的了。于是,重寫(覆寫)便產(chǎn)生了,為了解決父類方法在子類中不適用,而讓子類重寫方法的方式。我們解決以上代碼需求如下:
class Animal{public void printWhoIAm(){System.out.println("Animal")} } public class Dog extends Animal{//加上注解@Override可以強制進行重寫的檢查 防止自己重寫錯誤@Overridepublic void printWhoIAm(){System.out.println("Dog")}public static void main(String args[]){Dog dog = new Dog();dog.printWhoIAm();} } /* output: Dog */重寫的規(guī)則
重寫是對父類允許訪問的方法的實現(xiàn)過程進行重新編寫,返回值不變或者為子類、形參列表不能改變并且訪問控制權(quán)限不能嚴于父類。父類為default包訪問權(quán)限,則子類就為public或者default;若父類是public,則子類必須為public。
子類可以重寫父類的除了構(gòu)造器的任何方法。構(gòu)造器是和類名相同的,不能被子類繼承,因此也不可以被重寫。
重寫方法不能拋出新的檢查異常或者比被重寫方法申明更加寬泛的異常。例如: 父類的一個方法申明了一個檢查異常 IOException,但是在重寫這個方法的時候不能拋出 Exception 異常,因為 Exception 是 IOException 的父類,只能拋出 IOException 的子類異常。
子類可以重寫父類中訪問控制權(quán)限為private的方法嗎?
答案是不可以。父類中的private方法對子類來說是不可見的,就算子類中完全按照重寫要求定義方法,也不能算重寫父類中的方法,實際上只是子類新增的一個方法。所以,只有非private方法才可以被重寫。
super.方法()和this.方法()的區(qū)別
子類若是重寫了父類的方法,那么父類原來的這個方法還可以被調(diào)用嗎?答案是可以的,使用super對父類的方法進行調(diào)用。
class Animal{public void printWhoIAm(){System.out.println("Animal")} } public class Dog extends Animal{//加上注解@Override可以強制進行重寫的檢查 防止自己重寫錯誤@Overridepublic void printWhoIAm(){System.out.println("Dog")}public void print(){super.printWhoIAm();printWhoIAm();// this.printWhoIAm();}public static void main(String args[]){Dog dog = new Dog();dog.print();} } /* output: Animal Dog */使用this.方法()會先在本類中查找是否存在要調(diào)用的方法,如果不存在則查找父類中是否具備此方法。如果有則調(diào)用,否則出現(xiàn)編譯時錯誤。使用super.方法()會明確表示調(diào)用父類中的方法,直接去父類尋找要調(diào)用的方法。
重載和重寫的區(qū)別
| 參數(shù)列表 | 必須改 | 一定不能改 |
| 返回類型 | 可以修改 | 一定不能改 |
| 訪問控制權(quán)限 | 可以修改 | 不能比父類嚴格 |
| 異常 | 可以修改 | 可以減少或刪除,一定不能拋出新的或者更廣的異常 |
| 發(fā)生范圍 | 可以在一個類中也可以在子類中 | 在子類中 |
小結(jié)
需要注意的是重載和重寫的定義形式。引用菜鳥教程的兩句話和一張圖結(jié)束。
方法重載是一個類中定義了多個方法名相同,而他們的參數(shù)的數(shù)量不同或數(shù)量相同而類型和次序不同,則稱為方法的重載(Overloading)。
方法重寫是在子類存在方法與父類的方法的名字相同,而且參數(shù)的個數(shù)與類型一樣,返回值也一樣的方法,就稱為重寫(Overriding)
參考:
《Java編程思想》第四版
菜鳥教程http://www.runoob.com/java/java-override-overload.html
轉(zhuǎn)載于:https://www.cnblogs.com/myworld7/p/10398335.html
總結(jié)
以上是生活随笔為你收集整理的Java——重载和重写的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python基础-re模块
- 下一篇: 聊聊、Java SPI