Inheritance繼承

Employee 父
Manager 子

public繼承 維持不變 權限不變 可以轉換爲子類

//派生類可以向基類轉換,但是會丟失派生類的特性
 //反之,基類不可向派生類轉換     對象切割,以public
 //protected 和private 需使用強制轉換
 pa=reinterpret_cast<A*>(pb)//很危險!!!!!!!!!

protected繼承 修改訪問權限,全部變成protected
將基類中的public變成protected
private繼承 全部變成private,將基類中public,protected改爲private

構造函數和析構函數不能被繼承
子類構造必須要顯式構造父類

Manager(const Manager& other):Employee(other)//拷貝構造

派生類也可作爲基類

class Base
{
public:             //外部可以訪問
    int public_i_;
protected:          //內部可以訪問,可繼承子類可訪問
    int protected_i_;
private:            //類內部可訪問            不可繼承,子類不可訪問
    int private_i_;
};
class A:public Base;
Class B:protected Base;
class C:private Base;
class AA:public B{//可以訪問public_i_;};
//外部不可
class AA :public C
{
    //Base::public_i_;  //不可以 被private截斷
};

先構造父類,再子類
先析構子類,再父類
默認調用默認父類的構造函數,如果父類中沒有默認的構造函數,須在初始化列表中顯式的構造(A()base(0))

與父類相同函數名,會重寫,將父類的方法重寫,父類中的方法就不存在了

A a;
Base *p_base=&a;//只能夠父類指針子類指針,子類指針不可指向父類指針
p_base.GetNum();//調用的是父類的方法
//如果父類當中是虛函數,virtual GetNum(),會調用子類方法
Base *p_a=new B();//虛析構,只調用a,沒調用b

父類實現虛函數,從子類當中尋找最符合的方式,比較符合實際情況


base String
A MyString

String 
{
public:String(char *str="")
~String(){delete[]str_;}
protected:
    char *str_;};
MyString:public String
{
MyString(char *str="");
~MyString(){delete[]str_}
};

MyString str;//被構造了兩次,卻只析構了一次
MyString(char *str=""):String(str);//直接調用父類的構造函數,析構子類,析構父類,出錯
~String();//應該由父類的析構函數來 回收
由父類繼承來的東西,不要在此類當中進行顯式的操作!!!!!!!!
由誰創建的變量就由誰來管理!!!!!!!!

MyString str(“I Love”);
String *p_string=&str;
str+”Mark”;//調用子類的+
*pString+”Mark”//調用父類的+
//把父類的+做成虛函數,此時*pString+”Mark”調用子類的+


繼承的體系
父類的構造 父類成員的構造 子類構造
子類析構 父類成員的析構 父類析構


虛繼承
多重繼承
class A;有 int a
class B:public A;有int b
class C:public A;有int c
class D:public B, public C//菱形繼承
{
//有2個a,一個b和一個c
}
D.a訪問不明確(b的a或C的a?)
D d;
d.C::a;//明確a是哪個
d.B::a;

虛繼承
class B:virtual public A;
class C:virtual public A;
class D:virtual public B,virtual Public C;
此時,只有一個a


純虛函數,無法被實例化,需要子類強制性實現
抽象類要用純虛函數,不能創建對象,是其它類的基類,接口的作用

class Animal
{
public:
    virtual void Cry()=0;//純虛函數,無須實現,需要子類來實現
};
class Dog:public Animal
{
public:
};

構造函數不會被繼承,初始化列表是初始化自己的,父類的變量不能在初始化類表初始化

Manager(const String&name,const int lev,const int salapy_base=5000):Employee(name,lev/*父類變量*/),salapy_base_(salapy_base_),employees_(nummptr)/*子類變量*/{}//這樣,由於父類的在父類初始化屬於自己的,用自己的方式初始化
ls.Employee::salapy_base_;//父
ls.salapy_base_;//子

數據的重定義並非覆蓋,而是你有一個我也有一個(名字相同而已)


函數
只要函數名相同,就會構成重載
overload 重載 作用域相同情況下
overwrite 重寫 只要函數名相同就構成重定義
overread (虛函數)覆蓋


hsa-a 新類當中使用了某類來實現一些功能 組合
is-a 新類當中繼承類某類 來擴展一些功能 繼承

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章