有些類與類之間存在特殊的關係。
我們發現,定義這些類時,下級別的成員除了擁有上一級的共性,還有自己的特性。
這個時候我們就可以考慮利用繼承的技術,減少重複代碼。
繼承的好處:
++可減少重複代碼++
一、基本語法
class A : public B;
A 類稱爲子類 或 派生類
B 類稱爲父類 或 基類
例如我們看到很多網站中,都有公共的頭部,公共的底部,甚至公共的左側列表,只有中心內容不同。
接下來我們分別利用普通寫法和繼承的寫法來實現網頁中的內容,看一下繼承存在的意義以及好處。
普通實現:(繁瑣,難以實現,內容複雜,低級程序員)
//Java頁面
class Java
{
public:
void header()
{
cout << "首頁、公開課、登錄、註冊...(公共頭部)" << endl;
}
void footer()
{
cout << "幫助中心、交流合作、站內地圖...(公共底部)" << endl;
}
void left()
{
cout << "Java,Python,C++...(公共分類列表)" << endl;
}
void content()
{
cout << "JAVA學科視頻" << endl;
}
};
//Python頁面
class Python
{
public:
void header()
{
cout << "首頁、公開課、登錄、註冊...(公共頭部)" << endl;
}
void footer()
{
cout << "幫助中心、交流合作、站內地圖...(公共底部)" << endl;
}
void left()
{
cout << "Java,Python,C++...(公共分類列表)" << endl;
}
void content()
{
cout << "Python學科視頻" << endl;
}
};
//C++頁面
class CPP
{
public:
void header()
{
cout << "首頁、公開課、登錄、註冊...(公共頭部)" << endl;
}
void footer()
{
cout << "幫助中心、交流合作、站內地圖...(公共底部)" << endl;
}
void left()
{
cout << "Java,Python,C++...(公共分類列表)" << endl;
}
void content()
{
cout << "C++學科視頻" << endl;
}
};
void test01()
{
//Java頁面
cout << "Java下載視頻頁面如下: " << endl;
Java ja;
ja.header();
ja.footer();
ja.left();
ja.content();
cout << "--------------------" << endl;
//Python頁面
cout << "Python下載視頻頁面如下: " << endl;
Python py;
py.header();
py.footer();
py.left();
py.content();
cout << "--------------------" << endl;
//C++頁面
cout << "C++下載視頻頁面如下: " << endl;
CPP cp;
cp.header();
cp.footer();
cp.left();
cp.content();
}
int main() {
test01();
system("pause");
return 0;
}
但是運用繼承的話:
通過繼承,減少很多代碼量,就很舒服。
#include<iostream>
using namespace std;
#include<string>
//函數調用()運算符重載
class Basetool
{
public:
void head()
{
cout << "頁面設置,詳情信息……(頭部信息)" << endl;
}
void foot()
{
cout << "合作方式,快速加入……(底部信息)" << endl;
}
void left()
{
cout << "c++,python,java……(左側信息)" << endl;
}
};
class python: public Basetool
{
public:
void content()
{
cout << "python的界面(內容信息)……" << endl;
}
};
class cpp : public Basetool
{
public:
void content()
{
cout << "c++的界面(內容信息)……" << endl;
}
};
class java : public Basetool
{
public:
void content()
{
cout << "java的界面(內容信息)……" << endl;
}
};
void test01()
{
python py;
py.head();
py.foot();
py.left();
py.content();
cout << "+++++++++++++++++++++++" << endl;
cpp cp;
cp.head();
cp.foot();
cp.left();
cp.content();
cout << "+++++++++++++++++++++++" << endl;
java y;
y.head();
y.foot();
y.left();
y.content();
cout << "+++++++++++++++++++++++" << endl;
}
int main() {
test01();
system("pause");
return 0;
}
總結:
派生類中的成員,包含兩大部分:
一類是從基類繼承過來的,一類是自己增加的成員。
從基類繼承過過來的表現其共性,而新增的成員體現了其個性。
二、繼承的方式
繼承方式一共有三種:
- 公共繼承
- 保護繼承
- 私有繼承
邏輯如圖:
#include<iostream>
using namespace std;
#include<string>
//函數調用()運算符重載
class Base
{
public:
int m_A;
protected:
int m_B;
private:
int m_C;
};
//公共繼承
class Son1 : public Base
{
public:
void func()
{
m_A=32 ; //可訪問 public權限
m_B=3 ; //可訪問 protected權限,類外不可訪問,在繼承中,兒子可以訪問父親
//m_C; //不可訪問
}
};
void test01()
{
Son1 s1;
s1.m_A = 78;//其他類只能訪問到公共權限
//s1.m_B=2 保護權限類外不可訪問,
}
class Son2 : protected Base
{
public:
void func()
{
m_A; //可訪問 private權限,父類中public成員到子類變爲protected成員
m_B; //可訪問 private權限,父類中protected成員到子類變爲protected成員
//m_C; //不可訪問
}
};
void test02()
{
Son2 s;
//s.m_A; //不可訪問
}
class Son3 :private Base
{
public:
void func()
{
m_A; //可訪問 private權限,父類中public成員到子類變爲private成員
m_B; //可訪問 private權限,父類中protected成員到子類變爲private成員
//m_C; //不可訪問
}
};
void test03()
{
Son3 f;
//Son3是私有繼承,所以繼承Son3的屬性在GrandSon3中都無法訪問到
//m_A;
//m_B;
//m_C;
}
class grandson : public Son3
{
public:
void func()
{
m_A = 1;//到了Son3中,m_A,m_B變成了私有,即時是兒子,也訪問不到。
m_B = 2;
}
};
int main() {
test01();
system("pause");
return 0;
}
三、繼承中的對象模型
使用
進行操作。首先切換到本目錄
然後:
cl /d1 reportSingleClassLayoutSon hello.cpp
報告單個類的佈局+類名。
(tap鍵可補齊)
我們發現:
繼承後,父類的所有都來了包括私有,也佔用空間。
>父類中所有非靜態成員都被繼承下去了
>父類中私有成員被編譯器隱藏了,因此訪問不到,但是確實被繼承下去了。
#include<iostream>
using namespace std;
#include<string>
//函數調用()運算符重載
class Base
{
public:
int m_A;
protected:
int m_B;
private:
int m_C;
};
//公共繼承
class Son : public Base
{
public:
int m_D;
};
void test01()
{
//16
//父類中所有非靜態成員都被繼承下去了
//父類中私有成員被編譯器隱藏了,因此訪問不到,但是確實被繼承下去了。
cout << "子類的大小" << sizeof(Son) << endl;
}
int main() {
test01();
//test02();
system("pause");
return 0;
}
查看對象模型如圖: