成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

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

Sleepy / 2129人閱讀

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

動機

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

結(jié)論

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

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

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

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

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

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

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

列個表格大概是這樣:

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

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

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

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》中,作者也說了,盡可能的在申明,傳參,返回值的時候使用父類和接口,而不要使用實現(xiàn)類。

大概是這樣:

ArrayList strList = new ArrayList();    //這樣是耿直的寫法
List strList = new ArrayList();    //這樣更好,因為你可以換后面這個new

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

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

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

參考

c++ ref: polymorphism

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

轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/64969.html

相關(guān)文章

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

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

    smartlion 評論0 收藏0
  • Java編程那些再熟悉不過知識點(持續(xù)更新)

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

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

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

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

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

    ormsf 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<