1. 程式人生 > >關於繼承,不同繼承方式,對於派生類成員以及基類的可見性

關於繼承,不同繼承方式,對於派生類成員以及基類的可見性

通過繼承機制,可以利用已有的資料型別來定義新的資料型別。所定義的新的資料型別不僅擁有新定義的成員,而且還同時擁有舊的成員。我們稱已存在的用來派生新類的類為基類,又稱為父類。由已存在的類派生出的新類稱為派生類,又稱為子類。

  在C++語言中,一個派生類可以從一個基類派生,也可以從多個基類派生。從一個基類派生的繼承稱為單繼承;從多個基類派生的繼承稱為多繼承。

  派生類的定義格式

  單繼承的定義格式如下:

   class <派生類名>:<繼承方式><基類名>
    {
     <派生類新定義成員>
    };

  其中,<派生類名>是新定義的一個類的名字,它是從<基類名>中派生的,並且按指定的<繼承方式>派生的。<繼承方式>常使用如下三種關鍵字給予表示:

   public 表示公有基類;

   private 表示私有基類;

   protected 表示保護基類;

  多繼承的定義格式如下:

   class <派生類名>:<繼承方式1><基類名1>,<繼承方式2><基類名2>,…
    {
     <派生類新定義成員>
    };

  可見,多繼承與單繼承的區別從定義格式上看,主要是多繼承的基類多於一個。

  派生類的三種繼承方式

   公有繼承(public)、私有繼承(private)、保護繼承(protected)是常用的三種繼承方式。

  1. 公有繼承(public)

  公有繼承的特點是基類的公有成員和保護成員作為派生類的成員時,它們都保持原有的狀態,而基類的私有成員仍然是私有的。

  2. 私有繼承(private)

  私有繼承的特點是基類的公有成員和保護成員都作為派生類的私有成員,並且不能被這個派生類的子類所訪問。

  3. 保護繼承(protected)

  保護繼承的特點是基類的所有公有成員和保護成員都成為派生類的保護成員,並且只能被它的派生類成員函式或友元訪問,基類的私有成員仍然是私有的。

  下面列出三種不同的繼承方式的基類特性和派生類特性。

  不同繼承方式的基類和派生類特性

繼承方式 基類特性 派生類特性
公有繼承 public public
protected
private
protected
不可訪問
私有繼承 public private
protected
private
private
不可訪問
保護繼承 public protected
protected
private
protected
不可訪問

  為了進一步理解三種不同的繼承方式在其成員的可見性方面的區別,下面從三種不同角度進行討論。

  對於公有繼承方式:
 
  (1) 基類成員對其物件的可見性:

  公有成員可見,其他不可見。這裡保護成員同於私有成員。

  (2) 基類成員對派生類的可見性:

  公有成員和保護成員可見,而私有成員不可見。這裡保護成員同於公有成員。

  (3) 基類成員對派生類物件的可見性:

  公有成員可見,其他成員不可見。

  所以,在公有繼承時,派生類的物件可以訪問基類中的公有成員;派生類的成員函式可以訪問基類中的公有成員和保護成員。這裡,一定要區分清楚派生類的物件和派生類中的成員函式對基類的訪問是不同的。

  對於私有繼承方式:

  (1) 基類成員對其物件的可見性:

  公有成員可見,其他成員不可見。

  (2) 基類成員對派生類的可見性:

  公有成員和保護成員是可見的,而私有成員是不可見的。

  (3) 基類成員對派生類物件的可見性:

  所有成員都是不可見的。

  所以,在私有繼承時,基類的成員只能由直接派生類訪問,而無法再往下繼承。

  對於保護繼承方式:

  這種繼承方式與私有繼承方式的情況相同。兩者的區別僅在於對派生類的成員而言,對基類成員有不同的可見性。

  上述所說的可見性也就是可訪問性。關於可訪問性還有另的一種說法。這種規則中,稱派生類的物件對基類訪問為水平訪問,稱派生類的派生類對基類的訪問為垂直訪問。

  一般規則如下


   公有繼承時,水平訪問和垂直訪問對基類中的公有成員不受限制;

   私有繼承時,水平訪問和垂直訪問對基類中的公有成員也不能訪問;

   保護繼承時,對於垂直訪問同於公有繼承,對於水平訪問同於私有繼承。

  對於基類中的私有成員,只能被基類中的成員函式和友元函式所訪問,不能被其他的函式訪問。

  基類與派生類的關係

  任何一個類都可以派生出一個新類,派生類也可以再派生出新類,因此,基類和派生類是相對而言的。

  基類與派生類之間的關係可以有如下幾種描述:

   1. 派生類是基類的具體化

   類的層次通常反映了客觀世界中某種真實的模型。在這種情況下,不難看出:基類是對若干個派生類的抽象,而派生類是基類的具體化。基類抽取了它的派生類的公共特徵,而派生類通過增加行為將抽象類變為某種有用的型別。

   2. 派生類是基類定義的延續

   先定義一個抽象基類,該基類中有些操作並未實現。然後定義非抽象的派生類,實現抽象基類中定義的操作。例如,虛擬函式就屬此類情況。這時,派生類是抽象的基類的實現,即可看成是基類定義的延續。這也是派生類的一種常用方法。

   3. 派生類是基類的組合

   在多繼承時,一個派生類有多於一個的基類,這時派生類將是所有基類行為的組合。

  派生類將其本身與基類區別開來的方法是新增資料成員和成員函式。因此,繼承的機制將使得在建立新類時,只需說明新類與已有類的區別,從而大量原有的程式程式碼都可以複用,所以有人稱類是“可複用的軟體構件”。  

相關推薦

關於繼承不同繼承方式對於派生成員以及可見

通過繼承機制,可以利用已有的資料型別來定義新的資料型別。所定義的新的資料型別不僅擁有新定義的成員,而且還同時擁有舊的成員。我們稱已存在的用來派生新類的類為基類,又稱為父類。由已存在的類派生出的新類稱為派生類,又稱為子類。  在C++語言中,一個派生類可以從一個基類派生,也可以從多個基類派生。從一個基類派生的繼

派生成員的訪問

作用域分辨符:就是::用來限定要訪問的成員所在的類的名稱;表示式是:基類名::成員名;            //資料成員基類名::成員名(引數表)//成員函式加入作用域分辨符可以防止同名覆蓋,也可以保證訪問不出現二義性;(避免二義性,記憶體中只有一份拷貝,用到虛基類)例子:

Java不同編碼方式中英文字元所佔位元組數

1 public class Test { 2 3 public static void main(String[] args){ 4 5 String[] charsetNames={ 6

三種不同方式計算歐氏距離速度比較

def int list axis return arr () num ces import timeimport numpy as np#計算單行的歐氏距離def cal_1(vec): dist = np.linalg.norm(vec) sim = (1.

定義一個封裝矩形的長和寬;在定義一個繼承自定義的這個繼承中根據中封裝的矩形的長和寬求矩形的面積。

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace 封裝長方體 {    

模板方法和介面引數的聯合使用 [ 同一請求不同處理方式 ]

      在開發中,我們經常要進行網路請求,並且對返回的資料進行處理。但是不同的請求返回的資料不同,因此對資料的處理也不同。如何如何設計解析資料的型別或者方法成了一個難點。下面使用模板方法和介面引數

selenlum筆記(定位方式搜索cookie)

嵌入 pre htm sleep num 手機網站 check lose 設置 driver.get_cookies() 獲得cookie信息add_cookie(cookie_dict) 向cookie添加會話信息delete_cookie(name) 刪除特定(部

虛析構函數派生調用構造方法

div pub urn new turn col blog 徹底 () #include <iostream> using namespace std; class A{ public: A() { cout<<"construct A

thinkphp 5 自動生成模組最簡單方式一句程式碼

  直接在專案入口檔案中加上最後一句就夠了     可以不依賴自動生成檔案,直接使用預設目錄生成模組,例如: // 定義應用目錄 define('APP_PATH', __DIR__ . '/../application/'); // 載入框架引

Ajax案例-基於XML以POST方式完成省份-城市二級下拉聯動

<%@ page language="java" pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head&g

安裝包建立快捷方式開機啟動項配置檔案引數覆蓋窗體

//using IWshRuntimeLibrary; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; usin

java中內部類的建立四種情況三種方式及內部資料訪問許可權

內部類和外部類的關係,及內部靜態類的資料訪問許可權,宣告方式。 第一種,在外部類內部宣告使用內部類,內部類的型別為static和非 static型別,內部類資料型別為private,protected,public 型別的訪問許可權。外部類為非靜態宣告和許可權如下: p

【程式語言】C++繼承派生、虛

從已有的物件型別出發建立一種新的物件型別,使它部分或全部繼承原物件的特點和功能,這是面向物件設計方法中的基本特性之一。繼承不僅簡化了程式設計方法,顯著提高了軟體的重用性,而且還使得軟體更加容易維護。派生則是繼承的直接產物,它通過繼承已有的一個或多個類來產生一個新的類,通過派生

redisdubbo安裝方式zookeeper的啟動方式

1.redis啟動方式,直接啟動bin目錄下的 2.zookeeper啟動方式 3.dubbo啟動方式 下載https://github.com/alibaba/dubbo 進入dubbo的下載包進行執行命令達成war包 執行命令 mvn install

公有繼承派生Student對Person成員的訪問

題目內容:已知基類Person的定義如下:class Person{ char Name[20];char Sex;int Age;public:void Register(char *name, int age, char sex) ;void ShowMe();};請通過

第三十一節 C++ 繼承之如何在派生中呼叫被覆蓋的函式成員(方法)

#include <iostream> using namespace std; /*有些基類的方法在派生類被覆蓋,但有時我們需要呼叫基類的方法。 * 這裡提供了兩種方式去呼叫基類被覆蓋的

使用Javascript動態建立表格不同的方法巨大的執行時間差異!

本來是想測試一下使用Javascript生成一個比較大的表格,大概需要多長時間,一直認為這會是一個比較固定的時間。期間用了幾種不同的方法,發現效率相差太大了。下面是測試的具體說明: 目標:生成一個2000*5的表格,每個單元格的內容是行號+逗號+列號 方法一:使用cre

一套原始碼編譯多個APP不同的簽名包名介面欄位...

一套原始碼編譯多個 APP,不同簽名,不同介面等配置 線上原始碼地址,結合原始碼看比較容易理解 原始碼地址 作為一個剛入行一兩年的 程式碼 Copy 者 來說,這麼久沒有深入瞭解 Gradle 真的是一大遺憾,熟悉了 Gradle 之後開發效率能夠提高

使用js控制表單重複提交(1加鎖2事件方式3 EasyUI中解決表單重複提交)

方法一、var flag = true; $(function() { $("#interested").click(function() { beInterested(); }); }); function beInterested() { //$("#inte

微信小程序中的不同場景不同的判斷請求的時機

滾動 解決 不同 利用 png 就會 自由 bug onload 本來5月1之前就想寫一下一篇關於小程序不同場景下發送ajax請求的問題,但是放假的前一天,出了個大bug,就是因為我修改不同的場景下執行不同的邏輯造成的 1、首先,在小程序裏,微信做了很多的緩存,我們可以很