C++筆記 第四十五課 不同的繼承方式---狄泰學院
阿新 • • 發佈:2018-12-01
如果在閱讀過程中發現有錯誤,望評論指正,希望大家一起學習,一起進步。
學習C++編譯環境:Linux
第四十五課 不同的繼承方式
1.被忽略的細節
冒號(:)表示繼承關係,parent表示被繼承的類,public的意義是什麼?
2.有趣的問題
是否可以將繼承語句中的public換成protected或者private?如果可以,與public繼承有什麼區別?
45-1 有趣的嘗試—可以執行
#include <iostream> #include <string> using namespace std; class Parent { }; class Child_A : public Parent { }; class Child_B : protected Parent { }; class Child_C : private Parent { }; int main() { return 0; }
3.不同的繼承方式
C++中支援三種不同的繼承方式
public繼承
父類成員在子類中保持原有訪問級別
private繼承
父類成員在子類中變為私有成員
protected繼承
父類中的公有成員變為保護成員,其他成員保持不變
45-2 繼承與訪問級別深度實踐(**)
#include <iostream> #include <string> using namespace std; class Parent { protected: int m_a; protected: int m_b; public: int m_c; void set(int a, int b, int c) { m_a = a; m_b = b; m_c = c; } }; class Child_A : public Parent { public: void print() { cout << "m_a" << m_a << endl; cout << "m_b" << m_b << endl; cout << "m_c" << m_c << endl; } }; class Child_B : protected Parent { public: void print() { cout << "m_a" << m_a << endl; cout << "m_b" << m_b << endl; cout << "m_c" << m_c << endl; } }; class Child_C : private Parent { public: void print() { cout << "m_a" << m_a << endl; cout << "m_b" << m_b << endl; cout << "m_c" << m_c << endl; } }; int main() { Child_A a; Child_B b; Child_C c; a.m_c = 100; /*b.m_c = 100;//Child_B protection inherits from Parent, so all Parent members become protected members, so the outside world cannot access //Child_B保護繼承自Parent,所以所有的Parent成員全部變成了protected成員,因此外界無法訪問 c.m_c = 100;//Child_C protection inherits from Parent, so all Parent members become private members, so the outside world cannot access */ //Child_C保護繼承自Parent,所以所有的Parent成員全部變成了private成員,因此外界無法訪問 a.set(1,1,1); //b.set(2,2,2); //c.set(3,3,3); a.print(); b.print(); c.print(); return 0; }
4.遺憾的事實
一般而言,C++工程專案中只使用public繼承
C++的派生語言只支援一種繼承方式(public繼承)
protected和private繼承帶來的複雜性遠大於實用性
45-3.d 45-3.cs 45-3.java C++派生語言初探
45-3.d linux執行指令:gdc 45-3.d
module D_Demo; import std.stdio; import std.string; class Obj { protected: string mName; string mInfo; public: this() { mName = "Object"; mInfo = ""; } string name() { return mName; } string info() { return mInfo; } } class Point : Obj { private: int mX; int mY; public: this(int x, int y) { mX = x; mY = y; mName = "Point"; mInfo = format("P(%d, %d)", mX, mY); } int x() { return mX; } int y() { return mY; } } void main(string[] args) { writefln("D Demo"); // D Demo Point p = new Point(1, 2); writefln(p.name()); // Point writefln(p.info()); // P(1, 2) } 執行結果 D Demo Point P(1, 2)
45-3.cs linux執行: gmcs 45-3.cs
class Obj
{
protected string mName;
protected string mInfo;
public Obj()
{
mName = "Object";
mInfo = "";
}
public string name()
{
return mName;
}
public string info()
{
return mInfo;
}
}
class Point : Obj
{
private int mX;
private int mY;
public Point(int x, int y)
{
mX = x;
mY = y;
mName = "Point";
mInfo = "P(" + mX + ", " + mY + ")";
}
public int x()
{
return mX;
}
public int y()
{
return mY;
}
}
class Program
{
public static void Main(string[] args)
{
System.Console.WriteLine("C# Demo"); // C# Demo
Point p = new Point(1, 2);
System.Console.WriteLine(p.name()); // Point
System.Console.WriteLine(p.info()); // P(1, 2)
}
}
執行結果
C# Demo
Point
P(1, 2)
45-3.java linux執行:javac 45-3.java
class Obj
{
protected String mName;
protected String mInfo;
public Obj()
{
mName = "Object";
mInfo = "";
}
public String name()
{
return mName;
}
public String info()
{
return mInfo;
}
}
class Point extends Obj
{
private int mX;
private int mY;
public Point(int x, int y)
{
mX = x;
mY = y;
mName = "Point";
mInfo = "P(" + mX + ", " + mY + ")";
}
public int x()
{
return mX;
}
public int y()
{
return mY;
}
}
class Program {
public static void main(String[] args){
System.out.println("Java Demo"); // Java Demo
Point p = new Point(1, 2);
System.out.println(p.name()); // Point
System.out.println(p.info()); // P(1, 2)
}
}
執行結果
Java Demo
Point
P(1, 2)
小結
C++中支援3種不同的繼承方式
繼承方式直接影響父類成員在子類中的訪問屬性
一般而言,工程中只使用public的繼承方式
C++的派生語言中只支援public繼承方式