302班

          java突擊隊(duì)
          posts - 151, comments - 74, trackbacks - 0, articles - 14
            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

          Java中的重載

          Posted on 2007-04-26 15:37 停留的風(fēng) 閱讀(1027) 評論(0)  編輯  收藏 所屬分類: 快速前進(jìn)的Java

          在Java 中,同一個(gè)類中的2個(gè)或2個(gè)以上的方法可以有同一個(gè)名字,只要它們的參數(shù)聲明不同即可。在這種情況下,該方法就被稱為重載(overloaded ),這個(gè)過程稱為方法重載(method overloading )。方法重載是Java 實(shí)現(xiàn)多態(tài)性的一種方式。如果你以前從來沒有使用過一種允許方法重載的語言,這個(gè)概念最初可能有點(diǎn)奇怪。但是你將看到,方法重載是Java 最激動(dòng)人心和最有用的特性之一。

          當(dāng)一個(gè)重載方法被調(diào)用時(shí),Java 用參數(shù)的類型和(或)數(shù)量來表明實(shí)際調(diào)用的重載方法的版本。因此,每個(gè)重載方法的參數(shù)的類型和(或)數(shù)量必須是不同的。雖然每個(gè)重載方法可以有不同的返回類型,但返回類型并不足以區(qū)分所使用的是哪個(gè)方法。當(dāng)Java 調(diào)用一個(gè)重載方法時(shí),參數(shù)與調(diào)用參數(shù)匹配的方法被執(zhí)行。

          下面是一個(gè)說明方法重載的簡單例子:

          // Demonstrate method overloading.
          class OverloadDemo {
          void test() {
          System.out.println("No parameters");
          }

          // Overload test for one integer parameter.
          void test(int a) {
          System.out.println("a: " + a);
          }

          // Overload test for two integer parameters. void test(int a,int b) { System.out.println("a and b: " + a + " " + b);}

          // overload test for a double parameter

          double test(double a) {

          System.out.println("double a: " + a);

          return a*a; }}

          class Overload {

          public static void main(String args[]) {
          OverloadDemo ob = new OverloadDemo();
          double result;

          // call all versions of test()ob.test();ob.test(10);ob.test(10,20);result = ob.test(123.25);System.out.println("Result of ob.test(123.25): " + result);

          }
          }

          該程序產(chǎn)生如下輸出:

          No parameters

          a: 10
          a and b: 10 20
          double a: 123.25
          Result of ob.test(123.25): 15190.5625

          從上述程序可見,test()被重載了四次。第一個(gè)版本沒有參數(shù),第二個(gè)版本有一個(gè)整型參數(shù),第三個(gè)版本有兩個(gè)整型參數(shù),第四個(gè)版本有一個(gè)double 型參數(shù)。由于重載不受方法的返回類型的影響,test()第四個(gè)版本也返回了一個(gè)和重載沒有因果關(guān)系的值。

          當(dāng)一個(gè)重載的方法被調(diào)用時(shí),Java 在調(diào)用方法的參數(shù)和方法的自變量之間尋找匹配。但是,這種匹配并不總是精確的。在一些情況下,Java 的自動(dòng)類型轉(zhuǎn)換也適用于重載方法的自變量。例如,看下面的程序:

          // Automatic type conversions apply to overloading.
          class OverloadDemo {
          void test() {
          System.out.println("No parameters");
          }

          // Overload test for two integer parameters. void test(int a,int b) { System.out.println("a and b: " + a + " " + b);}

          // overload test for a double parameter
          void test(double a) {
          System.out.println("Inside test(double) a: " + a);
          }
          }

          class Overload {

          public static void main(String args[]) {
          OverloadDemo ob = new OverloadDemo();
          int i = 88;

          ob.test();ob.test(10,20);
          ob.test(i); // this will invoke test(double)
          ob.test(123.2); // this will invoke test(double)
          }
          }

          該程序產(chǎn)生如下輸出:

          No parameters
          a and b: 10 20
          Inside test(double) a: 88
          Inside test(double) a: 123.2

          在本例中,OverloadDemo 的這個(gè)版本沒有定義test(int) 。因此當(dāng)在Overload 內(nèi)帶整數(shù)參數(shù)調(diào)用test()時(shí),找不到和它匹配的方法。但是,Java 可以自動(dòng)地將整數(shù)轉(zhuǎn)換為double 型,這種轉(zhuǎn)換就可以解決這個(gè)問題。因此,在test(int) 找不到以后,Java 將i擴(kuò)大到double 型,然后調(diào)用test(double) 。當(dāng)然,如果定義了test(int) ,當(dāng)然先調(diào)用test(int) 而不會(huì)調(diào)用test(double) 。只有在找不到精確匹配時(shí),Java 的自動(dòng)轉(zhuǎn)換才會(huì)起作用。

          方法重載支持多態(tài)性,因?yàn)樗荍ava 實(shí)現(xiàn)“一個(gè)接口,多個(gè)方法”范型的一種方式。要理解這一點(diǎn),考慮下面這段話:在不支持方法重載的語言中,每個(gè)方法必須有一個(gè)惟一的名字。但是,你經(jīng)常希望實(shí)現(xiàn)數(shù)據(jù)類型不同但本質(zhì)上相同的方法。可以參考絕對值函數(shù)的例子。在不支持重載的語言中,通常會(huì)含有這個(gè)函數(shù)的三個(gè)及三個(gè)以上的版本,每個(gè)版本都有一個(gè)差別甚微的名字。例如,在C語言中,函數(shù)abs( )返回整數(shù)的絕對值,labs( ) 返回long 型整數(shù)的絕對值( ),而fabs( )返回浮點(diǎn)值的絕對值。盡管這三個(gè)函數(shù)的功能實(shí)質(zhì)上是一樣的,但是因?yàn)镃語言不支持重載,每個(gè)函數(shù)都要有它自己的名字。這樣就使得概念情況復(fù)雜許多。盡管每一個(gè)函數(shù)潛在的概念是相同的,你仍然不得不記住這三個(gè)名字。在Java 中就不會(huì)發(fā)生這種情況,因?yàn)樗械慕^對值函數(shù)可以使用同一個(gè)名字。確實(shí),Java 的標(biāo)準(zhǔn)的類庫包含一個(gè)絕對值方法,叫做abs ( )。這個(gè)方法被Java 的math 類重載,用于處理數(shù)字類型。Java 根據(jù)參數(shù)類型決定調(diào)用的abs()的版本。

          重載的價(jià)值在于它允許相關(guān)的方法可以使用同一個(gè)名字來訪問。因此,abs這個(gè)名字代表了它執(zhí)行的通用動(dòng)作(general action )。為特定環(huán)境選擇正確的指定(specific )版本是編譯器要做的事情。作為程序員的你,只需要記住執(zhí)行的通用操作就行了。通過多態(tài)性的應(yīng)用,幾個(gè)名字減少為一個(gè)。盡管這個(gè)例子相當(dāng)簡單,但如果你將這個(gè)概念擴(kuò)展一下,你就會(huì)理解重載能夠幫助你解決更復(fù)雜的問題。

          當(dāng)你重載一個(gè)方法時(shí),該方法的每個(gè)版本都能夠執(zhí)行你想要的任何動(dòng)作。沒有什么規(guī)定要求重載方法之間必須互相關(guān)聯(lián)。但是,從風(fēng)格上來說,方法重載還是暗示了一種關(guān)系。這就是當(dāng)你能夠使用同一個(gè)名字重載無關(guān)的方法時(shí),你不應(yīng)該這么做。例如,你可以使用sqr這個(gè)名字來創(chuàng)建一種方法,該方法返回一個(gè)整數(shù)的平方和一個(gè)浮點(diǎn)數(shù)值的平方根。但是這兩種操作在功能上是不同的。按照這種方式應(yīng)用方法就違背了它的初衷。在實(shí)際的編程中,你應(yīng)該只重載相互之間關(guān)系緊密的操作。

          7.1.1 構(gòu)造函數(shù)重載
          除了重載正常的方法外,構(gòu)造函數(shù)也能夠重載。實(shí)際上,對于大多數(shù)你創(chuàng)建的現(xiàn)實(shí)的

          類,重載構(gòu)造函數(shù)是很常見的,并不是什么例外。為了理解為什么會(huì)這樣,讓我們回想上一章中舉過的Box類例子。下面是最新版本的Box類的例子:

          class Box { double width; double height; double depth;

          // This is the constructor for Box.

          Box(double w,double h,double d) {width = w; height = h;depth = d;

          }

          // compute and return volume double volume() { return width * height * depth;}}

          在本例中,Box() 構(gòu)造函數(shù)需要三個(gè)自變量,這意味著定義的所有Box對象必須給Box() 構(gòu)造函數(shù)傳遞三個(gè)參數(shù)。例如,下面的語句在當(dāng)前情況下是無效的:

          Box ob = new Box();

          因?yàn)锽ox( )要求有三個(gè)參數(shù),因此如果不帶參數(shù)的調(diào)用它則是一個(gè)錯(cuò)誤。這會(huì)引起一些重要的問題。如果你只想要一個(gè)盒子而不在乎 (或知道)它的原始的尺寸該怎么辦?或,如果你想用僅僅一個(gè)值來初始化一個(gè)立方體,而該值可以被用作它的所有的三個(gè)尺寸又該怎么辦?如果Box 類是像現(xiàn)在這樣寫的,與此類似的其他問題你都沒有辦法解決,因?yàn)槟阒荒軒齻€(gè)參數(shù)而沒有別的選擇權(quán)。

          幸好,解決這些問題的方案是相當(dāng)容易的:重載Box 構(gòu)造函數(shù),使它能處理剛才描述的情況。下面程序是Box 的一個(gè)改進(jìn)版本,它就是運(yùn)用對Box構(gòu)造函數(shù)的重載來解決這些問題的:

          /* Here,Box defines three constructors to initialize

          the dimensions of a box various ways.
          */
          class Box {

          double width; double height; double depth; // constructor used when all dimensions specified Box(double w,double h,double d) {

          width = w;
          height = h;
          depth = d;

          }

          // constructor used when no dimensions specified Box() { width = -1; // use -1 to indicate
          height = -1; // an uninitialized
          depth = -1; // box
          }

          // constructor used when cube is created Box(double len) { width = height = depth = len;}

          // compute and return volume double volume() { return width * height * depth;}}

          class OverloadCons {

          public static void main(String args[]) { // create boxes using the various constructorsBox mybox1 = new Box(10,20,15);Box mybox2 = new Box();Box mycube = new Box(7);

          double vol;

          // get volume of first box
          vol = mybox1.volume();
          System.out.println("Volume of mybox1 is " + vol);

          // get volume of second box
          vol = mybox2.volume();
          System.out.println("Volume of mybox2 is " + vol);
          // get volume of cube
          vol = mycube.volume();
          System.out.println("Volume of mycube is " + vol);

          }
          }

          該程序產(chǎn)生的輸出如下所示:

          Volume of mybox1 is 3000.0
          Volume of mybox2 is -1.0
          Volume of mycube is 343.0

          在本例中,當(dāng)new執(zhí)行時(shí),根據(jù)指定的自變量調(diào)用適當(dāng)?shù)臉?gòu)造函數(shù)。

          主站蜘蛛池模板: 黄石市| 汪清县| 金湖县| 贵南县| 大洼县| 满洲里市| 辽中县| 广昌县| 郓城县| 浦北县| 黄平县| 共和县| 深水埗区| 玉溪市| 青铜峡市| 米脂县| 蓝田县| 天水市| 阳城县| 准格尔旗| 台南县| 策勒县| 上林县| 太仓市| 太和县| 白城市| 临夏县| 婺源县| 昭觉县| 深州市| 和田市| 金坛市| 丹巴县| 平阴县| 昂仁县| 邵武市| 蓬安县| 西吉县| 车险| 金华市| 桓台县|