成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

《Java編程思想》筆記8.多態(tài)

chinafgj / 749人閱讀

摘要:多態(tài)的作用是消除類(lèi)型之間的耦合關(guān)系。編寫(xiě)構(gòu)造器準(zhǔn)則用盡可能簡(jiǎn)單的方法使對(duì)象進(jìn)入正常狀態(tài),如果可以的話(huà),避免調(diào)用其他方法。

點(diǎn)擊進(jìn)入我的博客

在面向?qū)ο蟮某绦蛟O(shè)計(jì)語(yǔ)言中,多態(tài)是繼數(shù)據(jù)抽象(封裝)和繼承之后的第三種基本特征。
多態(tài)通過(guò)分離做什么怎么做,從另一角度將接口和實(shí)現(xiàn)分離開(kāi)來(lái)。
多態(tài)的作用是消除類(lèi)型之間的耦合關(guān)系。

8.1 再論向上轉(zhuǎn)型

對(duì)象既可以作為它自己的本類(lèi)使用,也可以作為它的基類(lèi)使用。

8.1.1 忘記對(duì)象類(lèi)型

我們只寫(xiě)一個(gè)簡(jiǎn)單的方法,它接受基類(lèi)作為參數(shù),而不是那些特殊的導(dǎo)出類(lèi)。

public class Test {
    public static void main(String[] args) {
        func(new Unicycle());
        func(new Bicycle());
        func(new Tricycle());
    }

    public static void func(Cycle cycle) {
        cycle.ride();
    }
}

class Cycle {
    void ride() {}
}

class Unicycle extends Cycle {
    void ride() {
        System.out.println("Unicycle");
    }
}

class Bicycle extends Cycle {
    void ride() {
        System.out.println("Bicycle");
    }
}

class Tricycle extends Cycle {
    void ride() {
        System.out.println("Tricycle");
    }
}
8.2 轉(zhuǎn)機(jī)

func(Cycle cycle)接受一個(gè)Cycle引用,那么編譯器怎么才能知道這個(gè)Cycle引用指的是哪個(gè)具體對(duì)象呢?實(shí)際上,編譯器并不知道。

8.2.1 方法調(diào)用綁定

綁定:講一個(gè)方法調(diào)用同一個(gè)方法主體關(guān)聯(lián)起來(lái)被稱(chēng)作綁定。

前期綁定:程序執(zhí)行前進(jìn)行綁定(由編譯器和連接程序?qū)崿F(xiàn))叫做前期綁定。

后期綁定(動(dòng)態(tài)綁定、運(yùn)行時(shí)綁定):在運(yùn)行時(shí)根據(jù)對(duì)象的類(lèi)型進(jìn)行綁定。

Java中除了static方法和final方法(private方法屬于final方法)之外,其他所有的方法都是后期綁定。

在講解final關(guān)鍵字的時(shí)候講到final關(guān)鍵字曾經(jīng)可以提高運(yùn)行效率,原因就在于它可以關(guān)閉動(dòng)態(tài)綁定,必須前期綁定。

8.2.2 產(chǎn)生正確的行為

在編譯時(shí),編譯器不需要獲得任何特殊信息就能進(jìn)行正確的調(diào)用。

Cycle cycle = new Tricycle();
cycle.ride();
8.2.3 可擴(kuò)展性

一個(gè)良好的OOP程序中,大多數(shù)或所有方法都會(huì)遵循基類(lèi)的模型,而且只與基類(lèi)接口通信。
這樣的程序是可擴(kuò)展的,因?yàn)榭梢詮耐ㄓ玫幕?lèi)繼承出新的數(shù)據(jù)類(lèi)型。
多態(tài)是一項(xiàng)讓程序員“將改變的事物與未變的事物分離開(kāi)來(lái)”的重要技術(shù)。

8.2.4 缺陷:“覆蓋私有方法”

父類(lèi)的私有方法子類(lèi)是無(wú)法重載的,即子類(lèi)的方法是一個(gè)全新的方法

只有非private的方法才能被覆蓋

下述程序調(diào)用的依然是父類(lèi)的對(duì)應(yīng)方法

約定:子類(lèi)中的方法不能和父類(lèi)中的private方法同名,能用起個(gè)名字解決的問(wèn)題不要搞得那么復(fù)雜

public class Test {
    public static void main(String[] args) {
        Test test = new TestDemo();
        test.func();
        // Output: Test
    }

    private void func() {
        System.out.println("Test");
    }
}

class TestDemo extends Test {
    public void func() {
        System.out.println("TestDemo");
    }
}
8.2.5 缺陷:域和靜態(tài)方法

只有普通方法的調(diào)用是多態(tài)的

當(dāng)子類(lèi)對(duì)象轉(zhuǎn)型為父類(lèi)對(duì)象時(shí),任何域訪(fǎng)問(wèn)操作都由編譯器解析,因此不是多態(tài)的

如果某個(gè)方法是靜態(tài)的,那么他就不是多態(tài)的

8.3 構(gòu)造器和多態(tài)

構(gòu)造器不具有多態(tài)性,因?yàn)樗鼈円彩请[式聲明為static

8.3.1 構(gòu)造器的調(diào)用順序

基類(lèi)的構(gòu)造器總是在導(dǎo)出類(lèi)的構(gòu)造過(guò)程中被調(diào)用,而且按照繼承層次逐漸想和那個(gè)鏈接,以便每個(gè)基類(lèi)的構(gòu)造器都能得到調(diào)用。

因?yàn)橹挥谢?lèi)的構(gòu)造器才有恰當(dāng)?shù)姆椒ê蜋?quán)限來(lái)初始化自己的元素,所以必須令所有構(gòu)造器都得到調(diào)用,這樣才能正確的構(gòu)造對(duì)象。

沒(méi)有明確指定基類(lèi)構(gòu)造器,就是調(diào)用默認(rèn)構(gòu)造器

對(duì)象調(diào)用構(gòu)造器順序

調(diào)用基類(lèi)構(gòu)造器(從根構(gòu)造器開(kāi)始)

按聲明順序調(diào)用成員的初始化方法

調(diào)用導(dǎo)出類(lèi)的構(gòu)造器

8.3.2 繼承與清理

通過(guò)組合和繼承方法來(lái)創(chuàng)建新類(lèi)時(shí),永遠(yuǎn)不必?fù)?dān)心對(duì)象的清理問(wèn)題,子對(duì)象通常會(huì)留給GC進(jìn)行處理。

如果確實(shí)遇到清理的問(wèn)題,在清理方法中要先寫(xiě)子類(lèi)的清理邏輯,然后調(diào)用父類(lèi)的清理方法;即清理順序應(yīng)該和初始化順序相反。

8.3.3 構(gòu)造器內(nèi)部的多態(tài)方法的行為

如果在構(gòu)造器的內(nèi)部調(diào)用正在構(gòu)造的對(duì)象的某個(gè)動(dòng)態(tài)綁定方法,會(huì)發(fā)生什么情況?

初始化的實(shí)際過(guò)程:

在其他任何事情發(fā)生之前,將分配給對(duì)象的存儲(chǔ)空間初始化成二進(jìn)制的零。

如8.3.1中那樣調(diào)用基類(lèi)構(gòu)造器。因?yàn)樵诨?lèi)構(gòu)造器中調(diào)用了func(),其實(shí)是被覆蓋的func()方法。

按照聲明的順序調(diào)用成員的初始化方法。

調(diào)用導(dǎo)出類(lèi)的構(gòu)造器主體。

public class Test {
    public static void main(String[] args) {
        new Child(100);
    }
}

class Child extends Parent {
    private int i;
    void func() {
        System.out.println("Child func, i = " + i);
    }

    public Child(int i) {
        this.i = i;
        System.out.println("Before Child constructor, i = " + i);
        func();
        System.out.println("After Child constructor, i = " + i);
    }
}

class Parent {
    void func() {
        System.out.println("Parent func");
    }

    public Parent() {
        System.out.println("Before Parent constructor");
        func();
        System.out.println("After Parent constructor");
    }
}
Output:
Before Parent constructor
Child func, i = 0
After Parent constructor
Before Child constructor, i = 100
Child func, i = 100
After Child constructor, i = 100
編寫(xiě)構(gòu)造器準(zhǔn)則:

用盡可能簡(jiǎn)單的方法使對(duì)象進(jìn)入正常狀態(tài),如果可以的話(huà),避免調(diào)用其他方法。

在構(gòu)造器中唯一能夠安全調(diào)用的是基類(lèi)中的finalprivate方法,因?yàn)檫@些方法不會(huì)被覆蓋。上述代碼中把Parent中的func()變成private的會(huì)得到不一樣的結(jié)果。

8.4 協(xié)變返回類(lèi)型

子類(lèi)覆蓋(重寫(xiě))父類(lèi)的方法時(shí),可以返回父類(lèi)返回類(lèi)型的子類(lèi)。
這是JSE 5之后增加的功能,如下所示。Child中的func()返回的是父類(lèi)返回類(lèi)型List的子類(lèi)ArrayList。

class Child extends Parent {
    @Override
    ArrayList func() {
        return null;
    }
}

class Parent {
    List func() {
        return null;
    }
}
8.5 用繼承進(jìn)行設(shè)計(jì)

準(zhǔn)則:用繼承表達(dá)行為間的差異,用字段表達(dá)狀態(tài)上的變化。

8.5.1 純繼承與擴(kuò)展
純繼承

只有在基類(lèi)已經(jīng)建立的方法才可以在導(dǎo)出類(lèi)中被覆蓋,純粹的“is-a”的關(guān)系。

擴(kuò)展

extends關(guān)鍵詞的意思可以看出,仿佛是希望我們?cè)诨?lèi)的基礎(chǔ)上擴(kuò)展功能,即增加基類(lèi)中不存在的方法,這可以稱(chēng)為“”is-like-a“”的關(guān)系。

這樣的缺點(diǎn)就是擴(kuò)展部分不能被基類(lèi)訪(fǎng)問(wèn),主要是在向上轉(zhuǎn)型的時(shí)候。

8.5.2 向下轉(zhuǎn)型與運(yùn)行時(shí)類(lèi)型識(shí)別(RTTI)

向上轉(zhuǎn)型是安全的,因?yàn)榛?lèi)不會(huì)具有大于導(dǎo)出類(lèi)的接口。

向下轉(zhuǎn)型時(shí)會(huì)有運(yùn)行時(shí)類(lèi)型識(shí)別(Run-Time Type Identification)機(jī)制對(duì)類(lèi)型進(jìn)行檢查,如果發(fā)現(xiàn)轉(zhuǎn)型失敗,會(huì)拋出一個(gè)運(yùn)行時(shí)異常(ClassCastException)。

RTTI的內(nèi)容不僅包括轉(zhuǎn)型處理,還可以查看對(duì)象類(lèi)型。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/72199.html

相關(guān)文章

  • javascript設(shè)計(jì)模式與開(kāi)發(fā)實(shí)踐(一)- 多態(tài)

    摘要:當(dāng)我們對(duì)一些函數(shù)發(fā)出調(diào)用的消息時(shí),這些函數(shù)會(huì)返回不同的執(zhí)行結(jié)果,這是多態(tài)性的一種體現(xiàn),也是很多設(shè)計(jì)模式在中可以用高階函數(shù)來(lái)代替實(shí)現(xiàn)的原因。 PS:上一篇文章發(fā)表之后,很多朋友關(guān)注了本人的思否和掘金的博客,雖然關(guān)注的朋友還有有限,但足夠讓我把自己在技術(shù)上的問(wèn)題積累分享給大家,也希望大家能夠喜歡,同時(shí)能動(dòng)一動(dòng)手指,給一顆心(贊),博主會(huì)持續(xù)更新下去 多態(tài) 本文是《javascript設(shè)計(jì)模...

    wthee 評(píng)論0 收藏0
  • Java編程思想筆記14.類(lèi)型信息

    摘要:接口與類(lèi)型信息關(guān)鍵字的一種重要目標(biāo)就是允許程序員隔離構(gòu)件,進(jìn)而降低耦合性。如果你編寫(xiě)接口,那么就可以實(shí)現(xiàn)這一目標(biāo),但是通過(guò)類(lèi)型信息,這種耦合性還是會(huì)傳播出去接口并非是對(duì)解耦的一種無(wú)懈可擊的保障。 點(diǎn)擊進(jìn)入我的博客 運(yùn)行時(shí)類(lèi)型信息使得你可以在運(yùn)行時(shí)發(fā)現(xiàn)和使用類(lèi)型信息,主要有兩種方式: 傳統(tǒng)的RTTI,它假定我們?cè)诰幾g時(shí)已經(jīng)知道了所有的類(lèi)型; 反射機(jī)制,它允許我們?cè)谶\(yùn)行時(shí)發(fā)現(xiàn)和使用類(lèi)的...

    Hwg 評(píng)論0 收藏0
  • SegmentFault 技術(shù)周刊 Vol.32 - 七夕將至,你的“對(duì)象”還好嗎?

    摘要:很多情況下,通常一個(gè)人類(lèi),即創(chuàng)建了一個(gè)具體的對(duì)象。對(duì)象就是數(shù)據(jù),對(duì)象本身不包含方法。類(lèi)是相似對(duì)象的描述,稱(chēng)為類(lèi)的定義,是該類(lèi)對(duì)象的藍(lán)圖或原型。在中,對(duì)象通過(guò)對(duì)類(lèi)的實(shí)體化形成的對(duì)象。一類(lèi)的對(duì)象抽取出來(lái)。注意中,對(duì)象一定是通過(guò)類(lèi)的實(shí)例化來(lái)的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...

    李昌杰 評(píng)論0 收藏0
  • SegmentFault 技術(shù)周刊 Vol.32 - 七夕將至,你的“對(duì)象”還好嗎?

    摘要:很多情況下,通常一個(gè)人類(lèi),即創(chuàng)建了一個(gè)具體的對(duì)象。對(duì)象就是數(shù)據(jù),對(duì)象本身不包含方法。類(lèi)是相似對(duì)象的描述,稱(chēng)為類(lèi)的定義,是該類(lèi)對(duì)象的藍(lán)圖或原型。在中,對(duì)象通過(guò)對(duì)類(lèi)的實(shí)體化形成的對(duì)象。一類(lèi)的對(duì)象抽取出來(lái)。注意中,對(duì)象一定是通過(guò)類(lèi)的實(shí)例化來(lái)的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...

    Lyux 評(píng)論0 收藏0
  • SegmentFault 技術(shù)周刊 Vol.32 - 七夕將至,你的“對(duì)象”還好嗎?

    摘要:很多情況下,通常一個(gè)人類(lèi),即創(chuàng)建了一個(gè)具體的對(duì)象。對(duì)象就是數(shù)據(jù),對(duì)象本身不包含方法。類(lèi)是相似對(duì)象的描述,稱(chēng)為類(lèi)的定義,是該類(lèi)對(duì)象的藍(lán)圖或原型。在中,對(duì)象通過(guò)對(duì)類(lèi)的實(shí)體化形成的對(duì)象。一類(lèi)的對(duì)象抽取出來(lái)。注意中,對(duì)象一定是通過(guò)類(lèi)的實(shí)例化來(lái)的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...

    AaronYuan 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<