面向對象與面向過程最大的不同應該就是面向對象提供了類的機制,其中三大特性就是封裝、繼承、多態。本文主要討論C++類的封裝繼承與多態。
在正式討論封裝繼承多態前,我們先補充一個知識點,運算符重載
運算符重載:之前介紹過,函數可以進行重載,通過使用不同的類型的形參或不同個數的參數調用同名方法實現不同的功能。那麼運算符也是可以重載的,下例就演示如何重載複數的加法運算:
重載運算符規則:#include <iostream> using namespace std; class Complex { public: Complex() { real=0; imag=0; } Complex(double r,double i) { real=r; imag=i; } //聲明重載操作符 Complex operator+(Complex &c2); void display(); private: double real; double imag; }; void Complex::display() { cout<<"("<<real<<","<<imag<<"i)"<<endl; } //定義重載操作 Complex Complex::operator+(Complex &c2) { Complex c; c.real=real+c2.real; c.imag=imag+c2.imag; return c; } int main() { Complex c1(3,5),c2(5,-2),c3; c3=c1+c2; c3.display(); return 0; }
1、C++不允許用戶自己定義新的運算符,只能對已有的C++運算符進行重載。
2、C++不能重載的運算符只有5個:. .* :: sizeof ?:
3、重載後不能改變運算符運算對象的個數。
4、重載不能改變運算符的優先級別。
......等等
類的封裝:
將有關數據和操作代碼封裝在一個對象中,形成一個基本的單位,各個對象之間相互獨立,互不干擾;將對象中某些部分信息對外隱蔽,及隱蔽其內部細節,只留下少量接口,以便於外界聯繫,接受外界消息。類是對象的抽象,而對象是類的特例。
繼承與派生:
所謂繼承就是在一個已存在的類的基礎上建立一個新的類,通過繼承,一個子類從父類哪裏獲得了父類的特性,在加上屬於自己的特性就構成了新的子類。
子類的聲明方式一般形式爲(默認爲私有繼承)
派生類的構成:class 派生類名:[繼承方式] 基類名
{
派生類新增的成員
};
派生類成員的訪問屬性:1、接受基類所有成員(不包括構造函數和析構函數)
2、調整從基類接受的成員(在派生類中聲明一個與基類成員同名的成員可覆蓋基類成員)
3、在聲明派生類時增加新成員
派生類構造函數:公有繼承:不改變基類原有的訪問屬性
私有繼承:基類所有成員訪問屬性變爲私有
受保護繼承:基類公有成員和受保護成員的訪問屬性變爲受保護,私有屬性不變。
多重繼承:派生類構造函數名(總參數列表):基類構造函數名(參數列表)
{
派生類中新增的數據成員初始語句
}
派生類構造函數名(總參數列表):基類構造函數名(參數列表),子對象名(參數列表){}
class D:public A,protected B,private C{類D新增加的成員};
多繼承構造函數:
派生類構造函數名(總參數列表):基類1構造函數名(參數列表),基類2構造函數名(參數列表)
{
派生類中新增的數據成員初始語句
}
多繼承引起的二義性問題:(兩個基類有同樣的成員是區分方法)
class A { public: int i; void display(); }; class B { public: int i; void display(); }; class C:public A,public B { public: int a; void show(); }; int main { C c; c.A::display(); c.B::display(); c.A::i=3; return 0; };
虛基類:
C++提供虛基類的方法,使得在繼承間接共同基類時只保留一份成員。
class A { public: int data; void display(); }; class B:virtual A { public: int b; }; class C:virtual A { public: int c; }; class D:public B,public C { //此時從B,C中繼承來的A的部分只有一份 };
基類和派生類之間的轉化:
1、派生類對象可以向基類對象賦值。
2、派生類對象可替代基類對象向基類對象的引用進行賦值或初始化。
3、如果函數參數是基類對象或基類對象的引用,相應的實參可以是子類對象。
4、派生類對象的地址可以賦值給基類對象的指針變量。
類的多態性:
虛函數:多態的意思是一個事物有多種形態。在C++中,多態性是指具有不同功能的函數可以用同一個函數名,這樣就可以用一個函數名調用不同內容的函數。向不同對象發送消息,不同對象在接受時會產生不同的行爲。
虛函數的作用是允許在派生類中重新定義與基類同名的函數,並且可以通過基類指針或引用來訪問基類和派生類中的同名函數。
#include <iostream> #include <string> using namespace std; class Student { public: Student(int num,string name):num(num),name(name){} virtual void display();//將此函數聲明爲虛函數 protected: int num; string name; }; void Student::display() { cout<<num<<","<<name<<endl; } class Draduate:public Student { public: void display(); Draduate(int num,string name,int score):Student(num,name),score(score){} private: int score; }; void Draduate::display() { cout<<num<<","<<name<<","<<score<<endl; } int main() { Student stu(1,"YQW"); Draduate g(2,"WJJ",100); Student *p=&stu; p->display(); p=&g; p->display(); return 0; }
純虛函數:
抽象類:純虛函數是在聲明虛函數時被初始化爲0的函數,純虛函數沒有方法體。
不用定義對象而只是作爲一種基本類型用作繼承的類,稱爲抽象類,由於它常用來做基類,通常稱爲抽象基類。凡是包含純虛函數的類都是抽象類,包含純虛函數的類是無法建立對象的。