0627第五讲继承(1)概述
1继承的概述
1.1、定义:一个类可以拥有另外一个类的所有成员(除了三大件
:“构造函数、析构函数、赋值运算符重载函数”),称之为继承
类B继承类A B(子类、派生类)A(父类、基类)
1.2、继承父类后,子类的成员分为两部分:
1)继承自父类的部分(base part);
2)子类自己扩展的成员(apparent part);
1,3、父类的私有成员子类不能直接访问,必须通过公有成员函数间接访问。
1.4、子类可以扩展与父类函数原型相同(函数名、参数列表)的成员函数(重写、覆盖 overwrite)
重写:函数原型完全相同(函数名、参数列表完全相同,返回值可以不同)
重载:函数名相同,参数列表不同(只有返回类型不同不能构成重载)
当发生覆盖,base.fun();->父类函数被调用 derived.func();->子类函数被调用
调用被覆盖的父类版本函数:derived.baseclassname::func();
eg:
Derived(int _b,int _d):Base(_b){
d=_d;
}
Derived d1(20,30);//b,d
d1.print();//d = 30
d1.Base::print();//b = 20
1.5、继承的构造函数用初始化列表方式初始化时,用的是类名(参数),而组合用的是对象名(参数)
2、protected成员:受保护(多用于继承上)
父类中的protected成员,在子类中可以直接进行访问,对外不可以直接进行访问(相对子类public,相对类外private)
eg:
class Base{
protected:
int b;
};
class Derived:public Base{
public:
void print(){
cout<<"b ="<<b<<endl;//现在可以在子类中直接访问父类成员
cout<<"d = "<<d<<endl;
}
1.3、类的3种继承方式(对本类(继承父类的类)不产生影响,对它的子类或者对外才产生影响)
class Derived:[public][protected][private] Base
public:所有被继承的成员在子类中访问级别不变
protected:父类中public成员,在子类中为protected,其它不发生改变
private:所有被继承的成员在子类都是private(但是类内可以直接访问原本在父类中是public或者protected的成员,类外 比如主函数中就不能直接访问)
2、继承的使用
2.1继承主要是在以下情况下使用:
1)两个类之间有自然的继承关系,即一个类是另一个类的特例,如毕业生是一个学生,学生是一个人
2)实现代码重用(代码复用)。一个类可能需要使用其它类中定义的成语啊,此时可以定义一个派生类继承自该类,这样我们就不必重复编写代码了。
2.2组合和继承
1)组合:Has-A(有一个)eg: 圆有一个圆心,圆柱有两个圆
2)继承:Is-A(是一个)eg: 大学生是一个学生 医生是一个人
课堂练习:
1)Vehicle(继承方式练习):
char *name;char *made;char licensePlate[15];
int wheels;float totalOil;(升)float meter;(/升)
构造函数、析构函数、输出函数
Truck:继承自Vehicle
float weight;(货物重量)
class Vehicle{
protected:
char *name;
char *made;
char licensePlate[15];
int wheels;
float totalOil;// (升)
float meter;//(/升)
public:
Vehicle(char* _name = (char*)"",char* _made = (char*)"",char* _licensePlate=(char*)"",int _wheels = 0,float _totalOil = 0,float _meter = 0):wheels(_wheels),totalOil(_totalOil),meter(_meter){
name=new char[strlen(_name)+1];
strcpy(name, _name);
made=new char[strlen(_made)+1];
strcpy(made, _made);
strcpy(licensePlate, _licensePlate);
}
~Vehicle(){
if (name != NULL) {
delete []name;
name = NULL;
}
if (made != NULL) {
delete []made;
made = NULL;
}
}
void vPrint(){
cout<<"name:\t"<<name<<endl;
cout<<"made:\t"<<made<<endl;
cout<<"licensePlate:\t"<<licensePlate<<endl;
cout<<"wheels:\t"<<wheels<<endl;
cout<<"totalOil:\t"<<totalOil<<endl;
cout<<"meter:\t"<<meter<<endl;
}
};
class Truck:public Vehicle{
protected:
float weight;
char *task;
public:
Truck(char* _name = (char*)"",char* _made = (char*)"",char* _licensePlate=(char*)"",int _wheels = 0,float _totalOil = 0,float _meter = 0,float _weight = 0,char* _task = (char*)""):Vehicle(_name,_made,_licensePlate,_wheels,_totalOil,_meter),weight(_weight=0){
task=new char (strlen(_task)+1);
strcpy(task, _task);
}
~Truck(){
if (task != NULL) {
delete []task;
task = NULL;
}
}
void tPrint(){
vPrint();
cout<<"weight:\t"<<weight<<endl;
cout<<"task:\t"<<task<<endl;
}
float dis(){
return totalOil*meter;
}
};
class Car:public Vehicle{
protected:
int peoples;
public:
Car(char* _name = (char*)"",char* _made = (char*)"",char* _licensePlate=(char*)"",int _wheels = 0,float _totalOil = 0,float _meter = 0,int _peoples = 0):Vehicle(_name,_made,_licensePlate,_wheels,_totalOil,_meter),peoples(_peoples){
}
~Car(){
}
void CPrint(){
vPrint();
cout<<"peoples:\t"<<peoples<<endl;
}
float pNumber(){
peoples=totalOil*meter/100;
return peoples;
}
};
void car()
{
Vehicle v1((char*)"大众",(char*)"德国",(char*)"京A123456",4,50,100);
Truck t1((char*)"大众",(char*)"德国",(char*)"京B456789",4,80,80,20,(char*)"货运");
Car c1((char*)"老司机的奇瑞QQ",(char*)"北京",(char*)"京C666666",4,200,500,0);
v1.vPrint();
t1.tPrint();
cout<<"distance:\t"<<t1.dis()<<endl;
c1.CPrint();
cout<<"pNumber:\t"<<c1.pNumber()<<endl;
c1.CPrint();
}
int main(int argc, const char * argv[]) {
car();
return 0;
}
2)Point、Circle、Cylinder(组合与继承练习)
class Point0627{
protected:
int x;
int y;
public:
Point0627(int _x = 0,int _y = 0):x(_x),y(_y){
}
int getX(){
return x;
}
int getY(){
return y;
}
void setX(int _x = 0){
x=_x;
}
void setY(int _y = 0){
y=_y;
}
void print(){
cout<<"x = "<<x<<endl;
cout<<"y = "<<y<<endl;
}
};
class Circle0627:public Point0627{
protected:
int radius;
public:
Circle0627(int _x,int _y,int _radius):Point0627(_x,_y){
radius=_radius;
}
int getRadius(){
return radius;
}
void setRadius(int _radius = 1)
{
radius=_radius;
}
void print(){
Point0627::print();
cout<<"radius = "<<radius<<endl;
cout<<"getGirth = "<<getGirth()<<endl;
cout<<"getArea = "<<getArea()<<endl;
}
float getGirth(){
return 2*3.14*radius;
}
float getArea(){
return 3.14*radius*radius;
}
};
class Cylinder0627:public Circle0627{
protected:
int height;
public:
Cylinder0627(int _x = 0,int _y = 0,int _radius = 1,int _height = 1):Circle0627(_x,_y,_radius){
height = _height;
}
int getHeight(){
return height;
}
void setHeight(int _height = 1){
height=_height;
}
void print(){
Circle0627::print();
cout<<"height = "<<height<<endl;
cout<<"getArea = "<<getArea()<<endl;
cout<<"getvolum = "<<getVolume()<<endl;
}
float getVolume(){
return Circle0627::getArea()*height;
}
float getArea(){
return getGirth()*height+2*Circle0627::getArea();
}
};
int main(int argc, const char * argv[]) {
Point0627 p1(0,0);
p1.print();
Circle0627 c1(1,2,3);
c1.print();
Cylinder0627 cy1(0, 0, 1, 1);
cy1.print();
return 0;
}