C++中的三種繼承方式


1,被忽略的細節:

    1,冒號( :)表示繼承關系,Parent 表示被繼承的類,public 的意義是什么?

1 class Parent
2 {
3             
4 };
5         
6 class Child : public Parent
7 {
8         
9 };

      

2,有趣的問題:

    1,是否可以將繼承語句中的 public 換成 protected 或者 private?如果可以,與 public 繼承有什么區別?

   

3,有趣的嘗試編程實驗:

 1 #include <iostream>
 2 #include <string>
 3 
 4 using namespace std;
 5 
 6 class Parent
 7 {
 8 };
 9 
10 class Child_A : public Parent
11 {
12 };
13 
14 class Child_B : protected Parent
15 {
16 };
17 
18 class Child_C : private Parent
19 {
20 };
21 
22 int main()
23 {   
24     return 0;
25 }

    1,protected 和 private 地位對等,推理的角度可以過,實際的編譯結果也是同樣的結論;

    2,本文主要分析這三種繼承方式有何不同;

   

4,不同的繼承方式(這是父類成員在子類中被外界訪問的級別):

    1,C++ 中支持三種不同的繼承方式;

         1,public 繼承:

             1,父類成員在子類中保持原有訪問級別;

         2,private 繼承:

             1,父類成員在子類中變為私有成員;

         3,protected 繼承:

             1,父類中的公有成員變為保護成員,其它成員保持不變;        

    2,繼承成員的屬性:

 

         1,Max{繼承方式,父類成員訪問屬性};

         2,C++ 中的默認繼承方式為 private;

    3,繼承與訪問級別深度實踐編程實驗:

 1 #include <iostream>
 2 #include <string>
 3 
 4 using namespace std;
 5 
 6 class Parent
 7 {
 8 protected:
 9     int m_a;
10 protected:
11     int m_b;
12 public:
13     int m_c;
14     
15     void set(int a, int b, int c)
16     {
17         m_a = a;
18         m_b = b;
19         m_c = c;
20     }
21 };
22 
23 class Child_A : public Parent
24 {
25 public:
26     void print()
27     {
28         cout << "m_a" << m_a << endl;
29         cout << "m_b" << m_b << endl;
30         cout << "m_c" << m_c << endl;
31     }
32 };
33 
34 class Child_B : protected Parent
35 {
36 public:
37     void print()
38     {
39         cout << "m_a" << m_a << endl;
40         cout << "m_b" << m_b << endl;
41         cout << "m_c" << m_c << endl;
42     }
43 };
44 
45 class Child_C : private Parent
46 {
47 public:
48     void print()
49     {
50         cout << "m_a" << m_a << endl;
51         cout << "m_b" << m_b << endl;
52         cout << "m_c" << m_c << endl;
53     }
54 };
55 
56 int main()
57 {   
58     Child_A a;
59     Child_B b;
60     Child_C c;
61     
62     a.m_c = 100;
63     // b.m_c = 100;    // Child_B 保護繼承自 Parent, 所以所有 public 成員全部變成了 protected 成員, 因此外界無法訪問;
64     // c.m_c = 100;    // Child_C 私有繼承自 Parent, 所以所有的成員全部變成了 private 成員, 因此外界無法訪問;
65     
66     a.set(1, 1, 1);
67     // b.set(2, 2, 2);  // 保護繼承;
68     // c.set(3, 3, 3);  // 私有繼承;
69     
70     a.print();  // 繼承方式只影響繼承自父類成員的訪問方式,外界訪問子類方式無影響;
71     b.print();  // 繼承方式只影響繼承自父類成員的訪問方式,外界訪問子類方式無影響;
72     c.print();  // 繼承方式只影響繼承自父類成員的訪問方式,外界訪問子類方式無影響;
73     
74     return 0;
75 }

         1,父類中的訪問級別影響着子類的訪問,但是繼承級別不影響子類的訪問、影響其它外部類訪問父類中的成員;

      

5,遺憾的事實:

    1,一般而言,大型的 C++ 工程項目中只使用 public 繼承;

       1,這已經足夠了;

       2,保護繼承和私有繼承根本就沒什么用;

    2,C++ 的派生語言只支持一種繼承方式(public 繼承);

       1,Java、C# 等語言只有一種繼承方式即 public 繼承方式;

    3,protected 和 private 繼承帶來的復雜性遠大於實用性;

       1,僅在學術研究領域研究;

   

6,C++ 派生語言初探編程實驗:

    1,D 語言(在 Linux 中用 gdc 編譯,生成 *.out 文件):

 1 module D_Demo;  // 將下面的所有代碼定義為模塊,模塊名字為 
 2 D_Demo;
 3 
 4 import std.stdio;  // import 同 include
 5 import std.string;  // import 同 include
 6 
 7 class Obj  // 這里定義了一個 Obj 類
 8 {
 9 protected:
10     string mName;
11     string mInfo;
12     
13 public:
14     this()  // 這是 D 語言中的構造函數,D 語言中的構造函數統一的用 this 這個關鍵字表示,由 C++ 進化而來;
15     {
16         mName = "Object";
17         mInfo = "";
18     }
19     
20     string name()  // 定義兩個成員函數;
21     {
22         return mName;
23     }
24     
25     string info()
26     {
27         return mInfo;
28     }
29 }
30 
31 class Point : Obj  // 定義了一個類 Point,其繼承自 Obj,D 語言中的繼承方式默認的是 public 繼承;
32 {
33 private:
34     int mX;
35     int mY;
36     
37 public:
38     this(int x, int y)
39     {
40         mX = x;
41         mY = y;
42         mName = "Point";
43         mInfo = format("P(%d, %d)", mX, mY);  // 和 C 語言中的語法規則一樣;
44     }
45     
46     int x()
47     {
48         return mX;
49     }
50     
51     int y()
52     {
53         return mY;
54     }
55 }
56 
57 void main(string[] args)  // 程序運行的入口;
58 {
59     writefln("D Demo");        // D Demo;打印語句之后空一行,同 printf;
60     
61     Point p = new Point(1, 2);  // 動態生成 Point 對象;
62     
63     writefln(p.name());           // Point,公有繼承;
64     writefln(p.info());           // P(1, 2),公有繼承;
65 }

       1,沒學過 D 語言,但是要讀懂 D 語言的代碼是比較容易的;

       2,如果因工作需要要學習 D 語言程序設計,將是輕而易舉的事情;

    2,C# 語言(Linux 中用 gmcs 編譯,生成 *.exe 文件):

 1 class Obj  // 定義一個類 Obj;
 2 {
 3     protected string mName;  // 訪問屬性 protected;
 4     protected string mInfo;
 5     
 6     public Obj()  // 無返回值,函數名同類名,即構造函數,訪問屬性為 public;
 7     {
 8         mName = "Object";
 9         mInfo = "";
10     }
11     
12     public string name()
13     {
14         return mName;
15     }
16     
17     public string info()
18     {
19         return mInfo;
20     }
21 }
22 
23 class Point : Obj  // 定義一個類 Point,繼承自 Obj,只有一種 public 繼承方式;
24 {
25 
26     private int mX;
27     private int mY;
28 
29     public Point(int x, int y)  // 構造函數;
30     { 
31         mX = x;
32         mY = y;
33         mName = "Point";
34         mInfo = "P(" + mX + ", " + mY + ")";  // 通過 + 操作符來連接字符串和整型變量,最終得到一個字符串;C++ 中可以通過重載全局的 + 操作符就能夠連接一個字符串和一個整型變量最終得到一個字符串,別的語言中的特性,不明白的話,考慮下在 C++ 中如何實現;                                          
35     }
36     
37     public int x()
38     {
39         return mX;
40     }
41     
42     public int y()
43     {
44         return mY;
45     }
46 }
47 
48 class Program
49 {
50     public static void Main(string[] args)  // 程序入口
51     {
52         System.Console.WriteLine("C# Demo");    // C# Demo
53         
54         Point p = new Point(1, 2);
55         
56         System.Console.WriteLine(p.name());     // Point
57         System.Console.WriteLine(p.info());     // P(1, 2)
58         
59     }
60 }

    3,Java 程序:

 1 class Obj
 2 {
 3     protected String mName;
 4     protected String mInfo;
 5     
 6     public Obj()
 7     {
 8         mName = "Object";
 9         mInfo = "";
10     }
11     
12     public String name()
13     {
14         return mName;
15     }
16     
17     public String info()
18     {
19         return mInfo;
20     }
21 }
22 
23 class Point extends Obj  // extends 表示公有繼承,更加直觀;
24 {
25 
26     private int mX;
27     private int mY;
28 
29     public Point(int x, int y)
30     { 
31         mX = x;
32         mY = y;
33         mName = "Point";
34         mInfo = "P(" + mX + ", " + mY + ")";
35     }
36     
37     public int x()
38     {
39         return mX;
40     }
41     
42     public int y()
43     {
44         return mY;
45     }
46 }
47 
48 class Program {
49     public static void main(String[] args){  // 程序運行如口
50         System.out.println("Java Demo");    // Java Demo
51         
52         Point p = new Point(1, 2);
53         
54         System.out.println(p.name());       // Point
55         System.out.println(p.info());       // P(1, 2)
56     }
57 }

       1,現在已經有能力讀懂 D、C#、Java 語言程序了;

           1,C#、Java 可以從事網絡開發、游戲開發;

           2,D 語言可以從事系統開發;

       2,工程里面,僅僅使用 public 繼承就夠了;

      

7,小結:

    1,C++ 中支持 3 種不同的繼承方式;

    2,繼承方式直接影響父類成員在子類中的訪問屬性;

    3,一般而言,工程中只使用 public 的繼承方式;

    4,C++ 的派生語言中只支持 public 繼承方式;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM