繼承與派生
初識
類的繼承是新類從已有的舊類那裏獲得的特性,從已有的類產生新類的過程稱爲類的派生。通過繼承和派生,可以簡化代碼的編寫,提高開發效率。已有的類稱爲基類或父類,派生出的新類稱爲派生類或子類。根據派生類所擁有的基類數目不同,可以分爲單繼承和多繼承。
繼承的訪問控制
類的繼承有私有繼承、公有繼承、保護繼承3種。不同的繼承方式,導致派生類對基類成員的訪問能力有所不同。派生類對基類成員的訪問能力如下:
基類成員 |
繼承方式 |
派生類的訪問 |
|
||
private |
|
不可訪問 |
public |
private |
private |
protected |
|
private |
|
||
private |
|
不可訪問 |
public |
public |
public |
protected |
|
protected |
|
||
private |
|
不可訪問 |
public |
protected |
protected |
protected |
|
protected |
下面給出這三種繼承的代碼實現:
私有繼承:
#include<iostream>
using namespace std;
class Base
{
private:
int a;
public:
void inita(int x)
{
a = x;
}
int geta()
{
return a;
}
};
class Derived:private Base
{
private:
int b;
public:
void initb(int x,int y)
{
b = y;
inita(x);
}
int getb()
{
return b+geta();
}
};
int main(void)
{
Derived obj1;
obj1.initb(12,3);
//obj1.inita(10); Error語句無法執行執行
//cout<<obj1.geta()<<endl; Error語句無法執行執行
cout<<obj1.getb()<<endl;
return 0;
}
/* 運行結果:15 */
公有繼承:
#include<iostream>
using namespace std;
class Base
{
private:
int a;
public:
void inita(int x)
{
a = x;
}
int geta()
{
return a;
}
};
class Derived:public Base
{
private:
int b;
public:
void initb(int y)
{
b = y;
}
int getb()
{
return b+geta();
}
};
int main(void)
{
Derived obj1;
obj1.inita(12);
obj1.initb(3);
cout<<obj1.getb()<<endl;
return 0;
}
/* 運行結果:15 */
保護繼承:
#include<iostream>
using namespace std;
class Base
{
private:
int a;
public:
int b;
protected:
int c;
void initab(int aa,int bb)
{
a = aa;
b = bb;
}
int geta()
{
return a;
}
};
class Derived:protected Base
{
private:
int c;
public:
void initabc(int aa, int bb, int cc)
{
initab(aa,bb);
c = cc;
}
int getc()
{
return c+b+geta();
}
};
int main(void)
{
Derived obj1;
//obj1.initab(12,13); Error,'void Base::initab(int,int)' is protected
obj1.initabc(12,13,5);
cout<<obj1.getc()<<endl;
return 0;
}
/* 運行結果:30 */
#include<iostream>
using namespace std;
class Rectangle
{
double len,wid;
public:
Rectangle(double a = 0,double b = 0)
{
len = a;
wid = b;
}
friend double area(Rectangle &rect);
};
double area(Rectangle &rect)//友元函數不是類的成員函數,所以在類體外定義時不必加“類名::”
{
return rect.len*rect.wid;
}
int main(void)
{
Rectangle obj1(4,5);
cout<<"The area is "<<area(obj1);
return 0;
}
/* 運行結果:20 */
#include<iostream>
#include<cstring>
using namespace std;
class boy; // 聲明類boy
class girl
{
char *name;
int age;
public:
girl(char *n,int a) //定義構造函數
{
name = new char[strlen(n)+1];
strcpy(name,n);
age = a;
}
void prt(boy &b);// 開頭需要先聲明類boy,否則無法通過編譯
};
class boy
{
char *name;
int age;
public:
boy(char *n,int a)
{
name = new char[strlen(n)+1];
strcpy(name,n);
age = a;
}
friend void girl::prt(boy &b);//定義友元成員
};
void girl::prt(boy &b)
{
cout<<"The girl's name is "<<name<<", her age is "<<age<<endl;
cout<<"The boy's name is "<<b.name<<", his age is "<<b.age<<endl;
}
int main(void)
{
girl gl("Marry",18);
boy by("John",18);
gl.prt(by);
return 0;
}
/*
運行結果:
The girl's name is Marry, her age is 18
The boy's name is John, his age is 18
*/