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

資訊專欄INFORMATION COLUMN

c++中virtual關(guān)鍵字的作用與Java中多態(tài)的一點(diǎn)對(duì)比

Sleepy / 2086人閱讀

摘要:結(jié)論這個(gè)關(guān)鍵字的發(fā)揮作用是在子類去繼承父類的時(shí)候。在中,作者也說(shuō)了,盡可能的在申明,傳參,返回值的時(shí)候使用父類和接口,而不要使用實(shí)現(xiàn)類。

動(dòng)機(jī)

最近一直在使用C++寫win32程序,用了一些庫(kù),里面提供的類和demo各種是virtual這個(gè)關(guān)鍵字,一直不是很明白到底是啥用,于是查看了一些文檔,寫小程序來(lái)實(shí)驗(yàn)它的作用。

結(jié)論

virtual這個(gè)關(guān)鍵字的發(fā)揮作用是在子類去繼承父類的時(shí)候。比如:

class Person
{
public:
    void foo1()
    {
        // do ...
    }
    
    virtual void foo2() 
    {
        // do ...
    }
};

像上面的代碼,如果類Person就一直被實(shí)例化使用,但是沒(méi)有類去繼承它的話,那么這個(gè)virtual實(shí)際上并沒(méi)有什么卵用。foo2()方法和foo1()是一樣的。

當(dāng)它被繼承的時(shí)候,有兩種情況,覆寫(override)這個(gè)foo2()方法,或者不覆寫它。比如這樣:

class Student : public Person
{
public:
    void foo2() { // do something.. }
};

class Teacher : public Person
{
public:
    // no override
};

然后我們使用的時(shí)候,如果是子類的實(shí)例,調(diào)用foo2()方法,理所當(dāng)然是執(zhí)行子類中所定義的foo2()方法體。但是當(dāng)將這個(gè)子類的實(shí)例強(qiáng)制轉(zhuǎn)型成父類的實(shí)例(指針),再去執(zhí)行foo2()方法的時(shí)候,對(duì)應(yīng)的兩種情況:子類實(shí)現(xiàn)了父類中virtual方法的,調(diào)用子類的方法;子類中沒(méi)有override的,仍然是調(diào)用父類中的實(shí)現(xiàn)(這不是廢話么……)

列個(gè)表格大概是這樣:

// 大前提是父類中有個(gè)`virtual`方法`foo2()`
        是否override foo2()    調(diào)用子類實(shí)例的foo2()    強(qiáng)轉(zhuǎn)成父類后調(diào)用foo2()
子類1          是                執(zhí)行子類1的foo2()        執(zhí)行子類1的foo2()
子類2          否                執(zhí)行父類的foo2()         執(zhí)行父類的foo2()

// 另一種情況
// 大前提是父類中有個(gè)方法`foo2()`,但是沒(méi)有virtual關(guān)鍵字修飾
        是否override foo2()    調(diào)用子類實(shí)例的foo2()    強(qiáng)轉(zhuǎn)成父類后調(diào)用foo2()
子類1          是                執(zhí)行子類1的foo2()        執(zhí)行父類的foo2()
子類2          否                執(zhí)行父類的foo2()         執(zhí)行父類的foo2()
與Java的對(duì)比

我的感覺(jué)好像Java自帶這個(gè)多態(tài)的特性,不需要用什么關(guān)鍵字修飾,某個(gè)實(shí)例轉(zhuǎn)換成父類后調(diào)用方法,默認(rèn)就會(huì)調(diào)用子類的實(shí)現(xiàn)(如果有的話)。寫了個(gè)小demo實(shí)驗(yàn)了一下,果然如此。

public class Main {

    public static void main(String[] args) {
        Person p = new Person();
        p.foo(); // output: Person foo
        
        Student s = new Student();
        s.foo(); // output: Student foo
        
        Person ps = s;
        ps.foo(); // output: Student foo

    }
    
    static class Person {
        
        public void foo() {
            System.out.println("Person foo");
        }
    }
    
    static class Student extends Person {
        
        public void foo() {
            System.out.println("Student foo");
        }
    }

}

在《Effective Java 2e》中,作者也說(shuō)了,盡可能的在申明,傳參,返回值的時(shí)候使用父類和接口,而不要使用實(shí)現(xiàn)類。

大概是這樣:

ArrayList strList = new ArrayList();    //這樣是耿直的寫法
List strList = new ArrayList();    //這樣更好,因?yàn)槟憧梢該Q后面這個(gè)new

// 返回值和參數(shù)也是一樣,一般能使用接口就盡量使用接口,而不要寫死成實(shí)現(xiàn)類,這樣帶來(lái)更大的靈活性
public List buildStrList(List raw, AnyInterface interf) {
    // do xxxx
}
總結(jié)

virtual關(guān)鍵字修飾的方法在子類繼承實(shí)現(xiàn)后,就可以達(dá)到多態(tài)的目的(使用父類的指針依然可以調(diào)用到子類的實(shí)現(xiàn))。

Java中不需要這個(gè)關(guān)鍵字來(lái)達(dá)到多態(tài),覆寫方法自帶這個(gè)功能。

參考

c++ ref: polymorphism

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

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

相關(guān)文章

  • C++基礎(chǔ)語(yǔ)法(五)繼承——萬(wàn)字總結(jié),干貨滿滿

    摘要:繼承方式繼承方式限定了基類成員在派生類中的訪問(wèn)權(quán)限,包括公有的私有的和受保護(hù)的。所以子類給父類引用賦值也是可以的,相當(dāng)于給子類對(duì)象中繼承的父類部分起了別名。如圖成員函數(shù)也是如此,當(dāng)子類與父類具有函數(shù)名相同的函數(shù)時(shí),還是符合就近原則。 ...

    smartlion 評(píng)論0 收藏0
  • Java編程那些再熟悉不過(guò)知識(shí)點(diǎn)(持續(xù)更新)

    摘要:語(yǔ)言通過(guò)字節(jié)碼的方式,在一定程度上解決了傳統(tǒng)解釋型語(yǔ)言執(zhí)行效率低的問(wèn)題,同時(shí)又保留了解釋型語(yǔ)言可移植的特點(diǎn)。有針對(duì)不同系統(tǒng)的特定實(shí)現(xiàn),,,目的是使用相同的字節(jié)碼,它們都會(huì)給出相同的結(jié)果。項(xiàng)目主要基于捐贈(zèng)的源代碼。 本文來(lái)自于我的慕課網(wǎng)手記:Java編程中那些再熟悉不過(guò)的知識(shí)點(diǎn),轉(zhuǎn)載請(qǐng)保留鏈接 ;) 1. 面向?qū)ο蠛兔嫦蜻^(guò)程的區(qū)別 面向過(guò)程 優(yōu)點(diǎn): 性能比面向?qū)ο蟾摺R驗(yàn)轭愓{(diào)用時(shí)需要實(shí)例...

    taowen 評(píng)論0 收藏0
  • C++多態(tài)底層刨析(虛函數(shù)指針,虛函數(shù)表)

    摘要:當(dāng)子類繼承了父類并且子類重寫了父類的虛函數(shù)之后,我們可以看到此時(shí)子類中虛函數(shù)指針對(duì)應(yīng)的虛函數(shù)表中存的是子類經(jīng)過(guò)重寫的函數(shù)了。 前言:相信小伙伴們?cè)趯W(xué)習(xí)到C++面...

    callmewhy 評(píng)論0 收藏0
  • 談?wù)?em>Java面向?qū)ο?/b>

    摘要:也就是說(shuō),一個(gè)實(shí)例變量,在的對(duì)象初始化過(guò)程中,最多可以被初始化次。當(dāng)所有必要的類都已經(jīng)裝載結(jié)束,開(kāi)始執(zhí)行方法體,并用創(chuàng)建對(duì)象。對(duì)子類成員數(shù)據(jù)按照它們聲明的順序初始化,執(zhí)行子類構(gòu)造函數(shù)的其余部分。 類的拷貝和構(gòu)造 C++是默認(rèn)具有拷貝語(yǔ)義的,對(duì)于沒(méi)有拷貝運(yùn)算符和拷貝構(gòu)造函數(shù)的類,可以直接進(jìn)行二進(jìn)制拷貝,但是Java并不天生支持深拷貝,它的拷貝只是拷貝在堆上的地址,不同的變量引用的是堆上的...

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

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

0條評(píng)論

閱讀需要支付1元查看
<