<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    www.baidu.com

    JavaCode--我愛(ài)你,芳兒

    JavaStudy--我愛(ài)你,芳兒

    Java語(yǔ)法總結(jié) - 方法

    Java語(yǔ)法總結(jié) - 方法
    原文:http://www.tkk7.com/raylong1982/以下幾篇都是的....
    一、方法的重寫(xiě)。

    1、重寫(xiě)只能出現(xiàn)在繼承關(guān)系之中。當(dāng)一個(gè)類(lèi)繼承它的父類(lèi)方法時(shí),都有機(jī)會(huì)重寫(xiě)該父類(lèi)的方法。一個(gè)特例是父類(lèi)的方法被標(biāo)識(shí)為final。重寫(xiě)的主要優(yōu)點(diǎn)是能夠定義某個(gè)子類(lèi)型特有的行為。
        class Animal {
            public void eat(){
                System.out.println ("Animal is eating.");
            }
        }
        
        class Horse extends Animal{
            public void eat(){
                System.out.println ("Horse is eating.");
            }
        }

    2、對(duì)于從父類(lèi)繼承來(lái)的抽象方法,要么在子類(lèi)用重寫(xiě)的方式設(shè)計(jì)該方法,要么把子類(lèi)也標(biāo)識(shí)為抽象的。所以抽象方法可以說(shuō)是必須要被重寫(xiě)的方法。

    3、重寫(xiě)的意義。
    重寫(xiě)方法可以實(shí)現(xiàn)多態(tài),用父類(lèi)的引用來(lái)操縱子類(lèi)對(duì)象,但是在實(shí)際運(yùn)行中對(duì)象將運(yùn)行其自己特有的方法。
        public class Test {
            public static void main (String[] args) {
                Animal h = new Horse();
                h.eat();    
            }
        }

        class Animal {
            public void eat(){
                System.out.println ("Animal is eating.");
            }
        }
        
        class Horse extends Animal{
            public void eat(){
                System.out.println ("Horse is eating.");
            }
            public void buck(){
            }
        }

    一個(gè)原則是:使用了什么引用,編譯器就會(huì)只調(diào)用引用類(lèi)所擁有的方法。如果調(diào)用子類(lèi)特有的方法,如上例的h.buck(); 編譯器會(huì)抱怨的。也就是說(shuō),編譯器只看引用類(lèi)型,而不是對(duì)象類(lèi)型。

    4、重寫(xiě)方法的規(guī)則。
    若想實(shí)現(xiàn)一個(gè)合格重寫(xiě)方法,而不是重載,那么必須同時(shí)滿(mǎn)足下面的要求!

    A、重寫(xiě)規(guī)則之一:重寫(xiě)方法不能比被重寫(xiě)方法限制有更嚴(yán)格的訪問(wèn)級(jí)別。
    (但是可以更廣泛,比如父類(lèi)方法是包訪問(wèn)權(quán)限,子類(lèi)的重寫(xiě)方法是public訪問(wèn)權(quán)限。)
    比如:Object類(lèi)有個(gè)toString()方法,開(kāi)始重寫(xiě)這個(gè)方法的時(shí)候我們總?cè)菀淄沺ublic修飾符,編譯器當(dāng)然不會(huì)放過(guò)任何教訓(xùn)我們的機(jī)會(huì)。出錯(cuò)的原因就是:沒(méi)有加任何訪問(wèn)修飾符的方法具有包訪問(wèn)權(quán)限,包訪問(wèn)權(quán)限比public當(dāng)然要嚴(yán)格了,所以編譯器會(huì)報(bào)錯(cuò)的。

    B、重寫(xiě)規(guī)則之二:參數(shù)列表必須與被重寫(xiě)方法的相同。
    重寫(xiě)有個(gè)孿生的弟弟叫重載,也就是后面要出場(chǎng)的。如果子類(lèi)方法的參數(shù)與父類(lèi)對(duì)應(yīng)的方法不同,那么就是你認(rèn)錯(cuò)人了,那是重載,不是重寫(xiě)。

    C、重寫(xiě)規(guī)則之三:返回類(lèi)型必須與被重寫(xiě)方法的返回類(lèi)型相同。
    父類(lèi)方法A:void eat(){}  子類(lèi)方法B:int eat(){}  兩者雖然參數(shù)相同,可是返回類(lèi)型不同,所以不是重寫(xiě)。
    父類(lèi)方法A:int eat(){}   子類(lèi)方法B:long eat(){}  返回類(lèi)型雖然兼容父類(lèi),但是不同就是不同,所以不是重寫(xiě)。

    D、重寫(xiě)規(guī)則之四:重寫(xiě)方法不能拋出新的異常或者比被重寫(xiě)方法聲明的檢查異常更廣的檢查異常。但是可以?huà)伋龈伲邢藁蛘卟粧伋霎惓!?br />     import java.io.*;
        public class Test {
            public static void main (String[] args) {
                Animal h = new Horse();
                try {
                    h.eat();    
                }
                catch (Exception e) {
                }
            }
        }

        class Animal {
            public void eat() throws Exception{
                System.out.println ("Animal is eating.");
                throw new Exception();
            }
        }
        
        class Horse extends Animal{
            public void eat() throws IOException{
                System.out.println ("Horse is eating.");
                throw new IOException();
            }
        }
    這個(gè)例子中,父類(lèi)拋出了檢查異常Exception,子類(lèi)拋出的IOException是Exception的子類(lèi),也即是比被重寫(xiě)的方法拋出了更有限的異常,這是可以的。如果反過(guò)來(lái),父類(lèi)拋出IOException,子類(lèi)拋出更為寬泛的Exception,那么不會(huì)通過(guò)編譯的。
    注意:這種限制只是針對(duì)檢查異常,至于運(yùn)行時(shí)異常RuntimeException及其子類(lèi)不再這個(gè)限制之中。

    E、重寫(xiě)規(guī)則之五:不能重寫(xiě)被標(biāo)識(shí)為final的方法。

    F、重寫(xiě)規(guī)則之六:如果一個(gè)方法不能被繼承,則不能重寫(xiě)它。
    比較典型的就是父類(lèi)的private方法。下例會(huì)產(chǎn)生一個(gè)有趣的現(xiàn)象。
        public class Test {
            public static void main (String[] args) {
                //Animal h = new Horse();
                Horse h = new Horse();
                h.eat();
            }
        }

        class Animal {
            private void eat(){
                System.out.println ("Animal is eating.");
            }
        }
        
        class Horse extends Animal{
            public void eat(){
                System.out.println ("Horse is eating.");
            }
        }
    這段代碼是能通過(guò)編譯的。表面上看來(lái)違反了第六條規(guī)則,但實(shí)際上那是一點(diǎn)巧合。Animal類(lèi)的eat()方法不能被繼承,因此Horse類(lèi)中的eat()方法是一個(gè)全新的方法,不是重寫(xiě)也不是重載,只是一個(gè)只屬于Horse類(lèi)的全新的方法!這點(diǎn)讓很多人迷惑了,但是也不是那么難以理解。
    main()方法如果是這樣:
        Animal h = new Horse();
        //Horse h = new Horse();
        h.eat();
    編譯器會(huì)報(bào)錯(cuò),為什么呢?Horse類(lèi)的eat()方法是public的啊!應(yīng)該可以調(diào)用啊!請(qǐng)牢記,多態(tài)只看父類(lèi)引用的方法,而不看子類(lèi)對(duì)象的方法!


    二、方法的重載。
    重載是有好的,它不要求你在調(diào)用一個(gè)方法之前轉(zhuǎn)換數(shù)據(jù)類(lèi)型,它會(huì)自動(dòng)地尋找匹配的方法。方法的重載是在編譯時(shí)刻就決定調(diào)用哪個(gè)方法了,和重寫(xiě)不同。最最常用的地方就是構(gòu)造器的重載。

    1、基本數(shù)據(jù)類(lèi)型參數(shù)的重載。
        public class Test {
            static void method(byte b){
                System.out.println ("method:byte");
            }
            static void method(short s){
                System.out.println ("method:short");
            }
            static void method(int i){
                System.out.println ("method:int");
            }
            static void method(float f){
                System.out.println ("method:float");
            }
            static void method(double d){
                System.out.println ("method:double");
            }
            public static void main (String[] args) {
                method((byte)1);
                method('c');
                method(1);
                method(1L);
                method(1.1);
                method(1.1f);
            }
        }
    輸出結(jié)果:
    method:byte
    method:int
    method:int
    method:float
    method:double
    method:float

    可以看出:首先要尋找的是數(shù)據(jù)類(lèi)型正好匹配方法。如果找不到,那么就提升為表達(dá)能力更強(qiáng)的數(shù)據(jù)類(lèi)型,如上例沒(méi)有正好容納long的整數(shù)類(lèi)型,那么就轉(zhuǎn)換為float類(lèi)型的。如果通過(guò)提升也不能找到合適的兼容類(lèi)型,那么編譯器就會(huì)報(bào)錯(cuò)。反正是不會(huì)自動(dòng)轉(zhuǎn)換為較小的數(shù)據(jù)類(lèi)型的,必須自己強(qiáng)制轉(zhuǎn)換,自己來(lái)承擔(dān)轉(zhuǎn)變后果。

    char類(lèi)型比較特殊,如果找不到正好匹配的類(lèi)型,它會(huì)轉(zhuǎn)化為int而不是short,雖然char是16位的。


    2、重載方法的規(guī)則。

    A、被重載的方法必須改變參數(shù)列表。
    參數(shù)必須不同,這是最重要的!不同有兩個(gè)方面,參數(shù)的個(gè)數(shù),參數(shù)的類(lèi)型,參數(shù)的順序。

    B、被重載的方法與返回類(lèi)型無(wú)關(guān)。
    也就是說(shuō),不能通過(guò)返回類(lèi)型來(lái)區(qū)分重載方法。

    C、被重載的方法可以改變?cè)L問(wèn)修飾符。
    沒(méi)有重寫(xiě)方法那樣嚴(yán)格的限制。

    D、被重載的方法可以聲明新的或者更廣的檢查異常。
    沒(méi)有重寫(xiě)方法那樣嚴(yán)格的限制。

    E、方法能夠在一個(gè)類(lèi)中或者在一個(gè)子類(lèi)中被重載。


    3、帶對(duì)象引用參數(shù)的方法重載。
        class Animal {}
        class Horse extends Animal{}
        
        public class Test {
            static void method(Animal a){
                System.out.println ("Animal is called.");
            }
            static void method(Horse h){
                System.out.println ("Horse is called.");
            }
            public static void main (String[] args) {
                Animal a = new Animal();
                Horse h = new Horse();
                Animal ah = new Horse();
                
                method(a);
                method(h);
                method(ah);
            }
        }
    輸出結(jié)果是:
    Animal is called.
    Horse is called.
    Animal is called.
    前兩個(gè)輸出沒(méi)有任何問(wèn)題。第三個(gè)方法為什么不是輸出“Horse is called.”呢?還是那句老話(huà),要看引用類(lèi)型而不是對(duì)象類(lèi)型,方法重載是在編譯時(shí)刻就決定的了,引用類(lèi)型決定了調(diào)用哪個(gè)版本的重載方法。


    4、重載和重寫(xiě)方法區(qū)別的小結(jié)。
    如果能徹底弄明白下面的例子,說(shuō)明你對(duì)重載和重寫(xiě)非常了解了,可以結(jié)束這節(jié)的復(fù)習(xí)了。
        class Animal {
            public void eat(){
                System.out.println ("Animal is eating.");    
            }
        }
        class Horse extends Animal{
            public void eat(){
                System.out.println ("Horse is eating.");    
            }
            public void eat(String food){
                System.out.println ("Horse is eating " + food);
            }
        }
        
        public class Test {
            public static void main (String[] args) {
                Animal a = new Animal();
                Horse h = new Horse();
                Animal ah = new Horse();
                
                a.eat();
                h.eat();
                h.eat("apple");
                ah.eat();
                //a.eat("apple");
                //ah.eat("apple");
            }
        }

    四個(gè)輸出分別是什么?被注釋的兩條語(yǔ)句為什么不能通過(guò)編譯?
    第一條:a.eat(); 普通的方法調(diào)用,沒(méi)有多態(tài),沒(méi)什么技術(shù)含量。調(diào)用了Animal類(lèi)的eat()方法,輸出:Animal is eating.
    第二條:h.eat(); 普通的方法調(diào)用,也沒(méi)什么技術(shù)含量。調(diào)用了Horse類(lèi)的eat()方法,輸出:Horse is eating.
    第三條:h.eat("apple"); 重載。Horse類(lèi)的兩個(gè)eat()方法重載。調(diào)用了Horse類(lèi)的eat(String food)方法,輸出:Horse is eating apple
    第四條:ah.eat(); 多態(tài)。前面有例子了,不難理解。輸出:Horse is eating.
    第五條:a.eat("apple"); 低級(jí)的錯(cuò)誤,Animal類(lèi)中沒(méi)有eat(String food)方法。因此不能通過(guò)編譯。
    第六條:ah.eat("apple"); 關(guān)鍵點(diǎn)就在這里。解決的方法還是那句老話(huà),不能看對(duì)象類(lèi)型,要看引用類(lèi)型。Animal類(lèi)中沒(méi)有eat(String food)方法。因此不能通過(guò)編譯。

    小結(jié)一下:多態(tài)不決定調(diào)用哪個(gè)重載版本;多態(tài)只有在決定哪個(gè)重寫(xiě)版本時(shí)才起作用。
    重載對(duì)應(yīng)編譯時(shí),重寫(xiě)對(duì)應(yīng)運(yùn)行時(shí)。夠簡(jiǎn)潔的了吧!


    三、構(gòu)造方法。
    構(gòu)造方法是一種特殊的方法,沒(méi)有構(gòu)造方法就不能創(chuàng)建一個(gè)新對(duì)象。實(shí)際上,不僅要調(diào)用對(duì)象實(shí)際類(lèi)型的構(gòu)造方法,還要調(diào)用其父類(lèi)的構(gòu)造方法,向上追溯,直到Object類(lèi)。構(gòu)造方法不必顯式地調(diào)用,當(dāng)使用new關(guān)鍵字時(shí),相應(yīng)的構(gòu)造方法會(huì)自動(dòng)被調(diào)用。

    1、構(gòu)造方法的規(guī)則。
    A、構(gòu)造方法能使用任何訪問(wèn)修飾符。包括private,事實(shí)上java類(lèi)庫(kù)有很多都是這樣的,設(shè)計(jì)者不希望使用者創(chuàng)建該類(lèi)的對(duì)象。

    B、構(gòu)造方法的名稱(chēng)必須與類(lèi)名相同。這樣使得構(gòu)造方法與眾不同,如果我們遵守sun的編碼規(guī)范,似乎只有構(gòu)造方法的首字母是大寫(xiě)的。

    C、構(gòu)造方法不能有返回類(lèi)型。
    反過(guò)來(lái)說(shuō),有返回類(lèi)型的不是構(gòu)造方法
        public class Test {
            int Test(){
                return 1;
            }
        }
    這個(gè)方法是什么東西?一個(gè)冒充李逵的李鬼而已,int Test()和其他任何普通方法沒(méi)什么兩樣,就是普通的方法!只不過(guò)看起來(lái)很惡心,類(lèi)似惡心的東西在考試卷子里比較多。

    D、如果不在類(lèi)中創(chuàng)建自己的構(gòu)造方法,編譯器會(huì)自動(dòng)生成默認(rèn)的不帶參數(shù)的構(gòu)造函數(shù)。
    這點(diǎn)很容易驗(yàn)證!寫(xiě)一個(gè)這樣簡(jiǎn)單的類(lèi),編譯。
    class Test {
    }
    對(duì)生成的Test.class文件反編譯:javap Test,可以看到:
    D:"JavaCode"bin>javap Test
    Compiled from "Test.java"
    class Test extends java.lang.Object{
        Test();
    }
    看到編譯器自動(dòng)添加的默認(rèn)構(gòu)造函數(shù)了吧!

    E、如果只創(chuàng)建了帶參數(shù)的構(gòu)造方法,那么編譯器不會(huì)自動(dòng)添加無(wú)參的構(gòu)造方法的!

    F、在每個(gè)構(gòu)造方法中,如果使用了重載構(gòu)造函數(shù)this()方法,或者父類(lèi)的構(gòu)造方法super()方法,那么this()方法或者super()方法必須放在第一行。而且這兩個(gè)方法只能選擇一個(gè),因此它們之間沒(méi)有順序問(wèn)題。

    G、除了編譯器生成的構(gòu)造方法,而且沒(méi)有顯式地調(diào)用super()方法,那么編譯器會(huì)插入一個(gè)super()無(wú)參調(diào)用。

    H、抽象類(lèi)有構(gòu)造方法。


    四、靜態(tài)方法的重載與重寫(xiě)(覆蓋)。

    1、靜態(tài)方法是不能被覆蓋的。可以分兩種情況討論:

    A、子類(lèi)的非靜態(tài)方法“覆蓋”父類(lèi)的靜態(tài)方法。
    這種情況下,是不能通過(guò)編譯的。

    class Father{
        
    static void print(){
            System.out.println (
    "in father  method");
        }
    }
    class Child extends Father{
        
    void print(){
            System.out.println (
    "in child method");
        }
    }

    static方法表示該方法不關(guān)聯(lián)具體的類(lèi)的對(duì)象,可以通過(guò)類(lèi)名直接調(diào)用,也就是編譯的前期就綁定了,不存在后期動(dòng)態(tài)綁定,也就是不能實(shí)現(xiàn)多態(tài)。子類(lèi)的非靜態(tài)方法是與具體的對(duì)象綁定的,兩者有著不同的含義。

    B、子類(lèi)的靜態(tài)方法“覆蓋”父類(lèi)靜態(tài)方法。
    這個(gè)覆蓋依然是帶引號(hào)的。事實(shí)上把上面那個(gè)例子Child類(lèi)的print方法前面加上static修飾符,確實(shí)能通過(guò)編譯!但是不要以為這就是多態(tài)!多態(tài)的特點(diǎn)是動(dòng)態(tài)綁定,看下面的例子:

    class Father{
        
    static void print(){
            System.out.println (
    "in father  method");
        }
    }
    class Child extends Father{
        
    static void print(){
            System.out.println (
    "in child method");
        }
    }

    class Test{
        
    public static void main (String[] args) {
            Father f 
    =new Child();
            f.print();
        }
    }

    輸出結(jié)果是:in father  method
    從這個(gè)結(jié)果可以看出,并沒(méi)有實(shí)現(xiàn)多態(tài)。
    但是這種形式很迷惑人,貌似多態(tài),實(shí)際編程中千萬(wàn)不要這樣搞,會(huì)把大家搞懵的!
    它不符合覆蓋表現(xiàn)出來(lái)的特性,不應(yīng)該算是覆蓋!
    總而言之,靜態(tài)方法不能被覆蓋。

    2、靜態(tài)方法可以和非靜態(tài)方法一樣被重載。
    這樣的例子太多了,我不想寫(xiě)例程了。看看java類(lèi)庫(kù)中很多這樣的例子。
    如java.util.Arrays類(lèi)的一堆重載的binarySearch方法。
    在這里提一下是因?yàn)椴橘Y料時(shí)看到這樣的話(huà)“sun的SL275課程說(shuō),靜態(tài)方法只能控制靜態(tài)變量(他們本身沒(méi)有),靜態(tài)方法不能被重載和覆蓋……”
    大家不要相信啊!可以重載的。而且靜態(tài)與非靜態(tài)方法可以重載。

    從重載的機(jī)制很容易就理解了,重載是在編譯時(shí)刻就決定的了,非靜態(tài)方法都可以,靜態(tài)方法怎么可能不會(huì)呢?


     

    芳兒寶貝.我愛(ài)你

    posted on 2007-12-08 15:05 wǒ愛(ài)伱--咾婆 閱讀(255) 評(píng)論(0)  編輯  收藏 所屬分類(lèi): JavaBaseFiles

    導(dǎo)航

    統(tǒng)計(jì)

    公告

    芳兒寶貝.我愛(ài)你


    黑客基地
    http://www.hackbase.com
    全球最大的黑客門(mén)戶(hù)網(wǎng)站


     最近在讀的書(shū):

    常用鏈接

    留言簿(1)

    隨筆分類(lèi)(37)

    JavaCode

    搜索

    積分與排名

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    主站蜘蛛池模板: 四虎影永久在线高清免费| 免费萌白酱国产一区二区三区| 中文字幕精品无码亚洲字| 亚洲日韩国产一区二区三区在线| 亚洲国产黄在线观看| 一个人免费观看在线视频www | 久久亚洲精品无码gv| 亚洲综合一区二区精品导航| 91av免费观看| 拍拍拍无挡免费视频网站| 黄页网站在线视频免费| 亚洲一区二区三区丝袜| 亚洲成年人啊啊aa在线观看| 无人在线观看完整免费版视频| 日韩免费观看一区| 亚洲日本VA中文字幕久久道具| 亚洲精品视频观看| 免费va人成视频网站全| 日本免费人成视频在线观看| 亚洲大尺度无码无码专线一区| 亚洲精品无码专区久久久| 嫖丰满老熟妇AAAA片免费看| 最刺激黄a大片免费网站| 日本亚洲欧洲免费天堂午夜看片女人员 | 亚洲午夜精品久久久久久人妖| 97无码免费人妻超级碰碰碰碰 | 在线a亚洲v天堂网2019无码| 日本一道高清不卡免费| 在线A级毛片无码免费真人| a级毛片在线免费观看| 国产乱妇高清无乱码免费| 大片免费观看92在线视频线视频| 羞羞网站在线免费观看| 日本系列1页亚洲系列| 亚洲第一页在线播放| 亚洲欧洲国产日韩精品| 亚洲男人的天堂在线播放| 亚洲AV福利天堂一区二区三| 久久久亚洲精品国产| 91大神亚洲影视在线| 亚洲最新黄色网址|