1. 程式人生 > >重寫(Override)與隱藏(hide)的區別

重寫(Override)與隱藏(hide)的區別

重寫必須滿足的條件:
1. 基類中的函式使用virtual修飾,即基類中的函式為虛擬函式;
2. 派生類中與基類中的這個virtual函式要有相同的函式原型(即:返回型別相同、函式名相同、形參列表相同);
下面我們看個簡單的程式:
#include <iostream>
using std::cout;
using std::endl;

class Person
{
public:
  virtual void Study()
  {
      cout << "這是基類中的方法" << endl;
  }
};

class Man : public Person
{
public:
    virtual void Study()
    {
        cout << "這是派生類中的方法" << endl;
    }
};

int main(void)
{
    Person *p = new Man;
    p -> Study();	// 輸出結果:這是派生類中的方法


    return 0;
}
Man類中的Study()函式對Person類中的Study()函式進行了重寫。 也許有些人認為:返回型別可以不同,這個我們可以做個測試,就是將Man類中的Study()方法改為返回值為int型別:
virtual void Study()
{
	cout << "這是派生類中的方法" << endl;
	return 0;
}
再次編譯,我們會發現,程式編譯都不能通過,提示返回型別衝突,重寫錯誤。

所以,重寫(Override)或覆蓋只會發生在多型中。對於基類中的非virtual函式,在派生類中重新定義只會導致隱藏。

隱藏:指的是派生類中的函式遮蔽了基類中的函式。

隱藏的規則:
1. 對於基類中的非virtual函式,如果派生類中存在和基類中相同的函式名,而不管返回值和形參列表是否相等;都會導致基類中的所有同名函式被派生類隱藏;
2. 對於基類中的virtual函式,如果派生類中存在和基類中相同的函式名,而且形參列表不同,就會導致基類中的所有同名的virtual函式被派生類隱藏;

注意:如果派生類中的函式和基類中的同名的virtual函式具有相同的形參列表和不同的返回值,那麼將不會隱藏基類中的函式,直接導致編譯錯誤(原因:編譯器此時會認為你是在重寫方法,而不是隱藏,只是返回型別寫錯了)。

下面我們看一個簡單的程式:

#include <iostream>

using std::cout;
using std::endl;

class Person
{
public:
    void Eat()
    {
        cout << "這是基類中的Eat方法" << endl;
    }


    void Work()
    {
        cout << "這是基類中不帶引數、返回值為void的Work函式" << endl;
    }

    void Work(int a)
    {
         cout << "這是基類中帶一個引數、返回值為void的Work函式" << endl;
    }

    virtual void Study()
    {
        cout << "這是基類中不帶引數的虛方法" << endl;
    }

    virtual void Study(int a)
    {
         cout << "這是基類中有一個引數的虛方法" << endl;
    }
};

class Man : public Person
{
public:
    int Work()
    {
        cout << "這是派生類中不帶引數、返回值為int的Work函式" << endl;
        return 0;
    }

    virtual  void Study(int a, int b)
    {
        cout << "這是派生類中虛的方法" << endl;
    }
};

int main(void)
{
    Man m;
    m.Eat();
 // m.Study();      //該函式已被派生類中定義的Study(int a, int b)隱藏,呼叫會導致編譯錯誤
 // m.Study(1);     //該函式已被派生類中定義的Study(int a, int b)隱藏,呼叫會導致編譯錯誤
    m.Study(1, 2);
    m.Work();
 // m.Work(1);      //該函式已被派生類隱藏中定義的Work()隱藏,呼叫會導致編譯錯誤
    return 0;
}

分析:在派生類中,沒有定義Eat()方法,所以派生類可以正常的呼叫基類中的Eat()方法,但是後面的Study()方法,在派生類中對其進行了定義,雖然函式原型不同,但也隱藏了基類中的所有名為Study()的函式,需要注意的是:如果派生類中的函式和基類中的同名的virtual函式具有相同的形參列表和不同的返回值,那麼將不會隱藏基類中的函式,直接導致編譯錯誤(原因:編譯器此時會認為你是在重寫方法,而不是隱藏,只是返回型別寫錯了)。關於這一點,你可以在Man中新增一個int Study()函式試一下。對於Work()函式,同樣是由於在派生類中定義了一個同名的函式,導致基類中過載的一組Work()函式都被遮蔽。

對於隱藏,我們從字面意思也可以看出,只是將基類中的同名的函式遮蔽了,並沒有將其銷燬,所以我們還是可以對其進行呼叫的。

主要有以下三種方法:

1. 在派生類中的函式中呼叫基類中的同名函式,比如:

    virtual  void Study()
    {
        Person::Study();       
    }

2. 在派生類中定義函式的前面使用using關鍵字顯式地宣告;
    using Person::Study;
    virtual void Study()
    {
        cout << "這是基類中不帶引數的虛方法" << endl;
    }

3. 採用派生類物件.基類名::基類中的方法;直接呼叫;例如:對於上面的程式,如果我們要呼叫基類中的Study()方法,我們可以這樣才呼叫:m.Person::Study(); 通過這三種方式,我們就可以訪問被派生類遮蔽了的基類中定義的函式。

總結:所謂重寫(或叫覆蓋),指的是派生類對基類中的虛擬函式進行方法體的改寫(要求函式原型相同);而隱藏指的是,派生類中的函式遮蔽了基類中同名的所有函式。(對virtual函式,要求函式名相同,形參列表不同;對非virtual函式,函式名相同即可)。注意:在繼承中不涉及過載的概念,因為過載最基本的要求是:在相同的作用域中,而繼承顯然屬於不同作用域。

相關推薦

重寫(Override)隱藏(hide)的區別

重寫必須滿足的條件:1. 基類中的函式使用virtual修飾,即基類中的函式為虛擬函式;2. 派生類中與基類中的這個virtual函式要有相同的函式原型(即:返回型別相同、函式名相同、形參列表相同); 下面我們看個簡單的程式: #include <iostream&g

【C++基礎】過載overload、重寫(覆蓋)override隱藏hide區別

過載overload 過載是指不同的函式使用相同的函式名,但是函式的引數個數或型別不同。呼叫的時候根據函式的引數來區別不同的函式。 相同的範圍(在同一個類中)函式名字相同引數不同virtual可有可無編譯期繫結,與多型無關 重寫(覆蓋)override 重寫/覆蓋是在在

C++ 過載、重寫(覆蓋)、重定義(隱藏) Java 過載、重寫(覆蓋)、隱藏區別

C++: 一、過載(overload) 指函式名相同,但是它的引數表列個數或順序,型別不同。但是不能靠返回型別來判斷。 (1)相同的範圍(在同一個作用域中) ; (2)函式名字相同; (3)引數不同; (4)virtual 關鍵字可有可無。 (5)返回值可以不同; 二、重寫(也稱為覆蓋

C++學習之多型及過載(overload),覆蓋(override),隱藏(hide)的區別

C++程式語言是一款應用廣泛,支援多種程式設計的計算機程式語言。我們今天就會為大家詳細介紹其中C++多型性的一些基本知識,以方便大家在學習過程中對此能夠有一個充分的掌握。   多型性可以簡單地概括為“一個介面,多種方法”,程式在執行時才決定呼叫的函式,它是面向物件程式設計

C++多型及過載(overload),覆蓋(override),隱藏(hide)的區別

C++程式語言是一款應用廣泛,支援多種程式設計的計算機程式語言。我們今天就會為大家詳細介紹其中C++多型性的一些基本知識,以方便大家在學習過程中對此能夠有一個充分的掌握。   多型性可以簡單地概括為“一個介面,多種方法”,程式在執行時才決定呼叫的函式,它是面向物件程式設

重寫(Override)重載(Overload)

super關鍵字 重載 自己的 例如 number int code 返回值 override 重寫(Override) 重寫是子類對父類的允許訪問的方法的實現過程進行重新編寫, 返回值和形參都不能改變。即外殼不變,核心重寫! 重寫的好處在於子類可以根據需要,定義特定於自己

20180813-Java 重寫(Override)過載(Overload)

Java 重寫(Override)與過載(Overload)   class Animal{ public void move(){ System.out.println("動物可以移動"); }} class Dog extends Animal{ public void move(){ S

Java——重寫(Override)過載(Overload)

1.  重寫(Override) 重寫是子類對父類的允許訪問的方法的實現過程進行重新編寫, 返回值和形參都不能改變。即外殼不變,核心重寫! 重寫的好處在於子類可以根據需要,定義特定於自己的行為。 也就是說子類能夠根據需要實現父類的方法。 重寫方法不能丟擲新的檢查異常或

Java - 21 Java 重寫(Override)過載(Overload)

Java 重寫(Override)與過載(Overload) 重寫(Override) 重寫是子類對父類的允許訪問的方法的實現過程進行重新編寫!返回值和形參都不能改變。即外殼不變,核心重寫! 重寫的好處在於子類可以根據需要,定義特定於自己的行為。 也就是說子類能夠根據需要實現父類的方法。 在面向

[C++]成員函式的過載(overload)、覆蓋(override)和隱藏(hide)

C++成員函式的過載、覆蓋和隱藏 1. 過載與覆蓋 成員函式被過載的特徵是: 具有相同的作用域(即同一個類定義中); 函式名字相同; 引數型別、順序或數目不同(包括); virtual 關鍵字可有可無。 覆蓋是指派生類重新實現(或者改寫)了基

overrideoverload的區別

過載(Overload) 過載---類中定義的方法可能有不同的版本 public book withdraw(double amt,string name) public double withdraw

【C++專題】過載(overload)、覆蓋(override)、隱藏(hide) 辨析

  寫正題之前,先給出幾個關鍵字的中英文對照,過載(overload),覆蓋(override),隱藏(hide)。在早期的C++書籍中,可能翻譯的人不熟悉專業用語(也不能怪他們,他們不是搞計算機程式設計的,他們是英語專業的),常常把過載(overload)和覆蓋(ov

C#中override重寫new隱藏區別,以及C#Java的Override區別

在C#中:override重寫,是指對父類中的虛方法(標記為override)或抽象方法(標記為abstract)進行重寫,實現新的功能,它必須與父類方法的簽名完全一致,而且與父類方法的可訪問性也必須一致new方法隱藏,是指在子類中重新定義一個簽名與父類的方法相同的方法,這個

方法的重寫重載的區別OverrideOverload)。重載的方法是否可以改變返回值的類型

改變 父類 div 之間 如果 如同 java 調用 ava 方法的重寫(Override)與重載(Overload)的區別。重載的方法是否可以改變返回值的類型?【基礎】 解釋: 方法的重寫overriding和重載Overloading是Java多態性的不同表現。 1、重

JAVA中的基礎-----過載重寫(覆蓋)的區別:overloadoverride

JAVA中多型的實現機制主要通過overload和override實現。 1)方法的過載:簡言之,就是指同一個類有多個同名的方法,這些方法擁有不同的引數(同名不同參)。可以認為是類中方法的多型性,也稱為編譯時多型。 2)方法的重寫(覆蓋):子類可覆蓋父類的方法,已達到“個性

方法過載overload重寫override區別

過載Overload 重寫Override 相同點 見下 見下 不同點 引數簽名必須不一致 引數簽名必須一致 不限制返回型別 返回型別必須一致 用於同一個類的所有方法(包括從父類中繼承而來的方法) 只用於子類重寫覆蓋父類的方法 不限制… 對方法的訪問許可權和丟擲異常

過載overlord重寫override區別

重寫只存在於子類與父類中,過載存在於一個類中。 具體區別如下: 一、重寫(override) override是重寫(覆蓋)了一個方法,以實現不同的功能。一般是用於子類在繼承父類時,重寫(重新實現)父類中的方法。 重寫(覆蓋)的規則: 1、重寫方

C#物件的三個特點:封裝,繼承,多型, 以及c#中隱藏(new)和方法重寫(override)和過載(overload)的區別

封裝 1)封裝原則:將不需要對外提供的內容都隱藏起來,把屬性都隱藏,提供公共方法對其訪問,通常有兩種訪問方式:set 設定,get 獲取。 2)封裝結果:存在但是不可見。 3) 訪問修飾符 宣告的可訪問性                                

重寫(overwrite)、重載(overload)和覆蓋(override)三者之間的區別

ride 傳遞 方法 子類 bsp 區別 參數 定義 load 覆蓋:子類繼承了父類的同名無參函數。當子類從父類繼承了一個無參函數,而又定義了一個同樣的無參函數,則子類定義的方法覆蓋父類的方法,稱為覆蓋。 重載:子類繼承了父類的同名有參函數。

C++重載、覆蓋、隱藏區別舉例

重載、覆蓋、隱藏參考博客:http://blog.csdn.net/hexi_2000/article/details/4392107//重載,覆蓋,隱藏舉例 #include <iostream> using namespace std; class A { public: int