继承的基本概念
- 一个A类可以继承继承另一个类B,那么称B为基类(父类),A为派生类(子类);
- 子类从父类继承了所有的成员,除了构造函数,析构函数,赋值运算符重载函数;
- 子类继承父类后,子类的成员分为两部分(1》继承父类的部分(base part)2》子类扩展自己的成员(appendent part));
- 虽然父类的成员被子类所继承,但是子类不能直接访问父类的私有成员,子类只能通过继承父类的共有成员函数来访问;
- 子类可以自己实现与父类成员函数原型相同(函数名、参数列表)的成员函数,称为覆盖或者重写(overwrite);
- 当通过父类对象调用被覆盖的函数时,父类版本的函数被调用,当通过子类对象调用覆盖父类的函数时,子类版本的函数被调用;
–子类可以调用被覆盖的父类版本的函数;eg:使用子类对象名.父类名::函数名–>s.father::print();
#include <iostream>
using namespace std;
class Person
{
public:
Person(){}
~Person(){}
char *getName()//通过调用共有的成员函数来访问父类的私有成员
{
return name;
}
void print()//子类实现和父类函数原型一致,重写
{
cout<<"i am father"<<endl;
}
private:
char *name;//1+3
int age;//4
};
class Student:public Person //一个学生是人的子类
{
public:
Student(){}
~Student(){}
void print()
{
//cout<<getName()<<endl;//调用父类的共有函数访问父类私有成员
cout<<"i am son"<<endl;
}
private:
//char *name;
//int age;
int id; // 4 + 8=12
};
int main()
{
cout<<sizeof(Person)<<endl;
cout<<sizeof(Student)<<endl;
Person q;
q.print();
Student p;
p.print();
return 0;
}
继承的使用示例:
#include <iostream>
using namespace std;
class Base
{
private:
int b_number;
public:
Base(int i):b_number(i){}
int get_number()
{
return b_number;
}
void print()
{
cout<<b_number<<endl;
}
};
class Derived:public Base
{
private:
int d_number;
public:
Derived(int i,int j):Base(i),d_number(j){}
void print()
{
cout<<get_number()<<" ";
cout<<d_number<<endl;
}
};
int main()
{
Base a(2);
Derived b(3,4);
a.print();
b.print();
cout<<"Derived继承的数字是:";
b.Base::print();
return 0;
}
保护成员(protected)的使用:
在上述示例中,子类虽然继承了父类的私有成员b_ number,但是在子类的print函数中依然不能直接访问该私有成员,子类只能通过继承之父类的公有成员函数.get_ number来访问。
如果父类里有protected类型的成员,在子类中可以直接访问,不需要借助父类的公有函数;但是protected类型的成员,对外界依然是隐藏的,对外就像private 类型一样。
注意:protect仅仅使用子类访问父类的私有成员
#include <iostream>
using namespace std;
class Base
{
protected:
int b_number;
public:
Base(int i):b_number(i){}
void print()
{
cout<<b_number<<endl;
}
};
class Derived:public Base
{
private:
int d_number;
public:
Derived(int i,int j):Base(i),d_number(j){}
void print()
{
cout<<b_number<<" ";//在子类可以直接访问继承父类的protected类型成员
cout<<d_number<<endl;
}
};
int main()
{
Base a(2);
Derived b(3,4);
a.print();
b.print();
cout<<"Derived继承的数字是:";
b.Base::print();
return 0;
}
继承的组合关系
继承使用的情况:
1>类之间有自然的继承关系,一个类是里另外一个类的特例,eg:一个学生是一个人
2>实现代码复用,一个类需要另外一个类的成员时
优点:
1.代码复用(code reuse); 2>修改代码简易化,只需要修改基类;
两个类的交互关系:1.组合(一个类包含这个类) 2.继承(一个类是里另外一个类的特例)
#include <iostream>
#define PI 3.1415926
using namespace std;
class Point
{
public:
Point():x(0),y(0){}
Point(double a,double b)
{
x=a;
y=b;
}
void frint()
{
cout<<"("<<x<<","<<y<<")"<<endl;
}
protected:
double x;
double y;
};
class Circle:public Point
{
public:
Circle():Point(),radius(0){}
Circle(double r,double a,double b):Point(a,b),radius(r){}
double area()
{
return (PI*radius*radius);
}
void frint()
{
cout<<"("<<x<<","<<y<<")"<<endl;
cout<<Circle::area()<<endl;
}
protected:
double radius;
};
class CyLinder:public Circle
{
public:
CyLinder():Circle(),height(0){}
CyLinder(double t,double r,double a,double b):Circle(a,b,r),height(t){}
double area()
{
return (2*Circle::area())+(2*PI*radius*height);
}
void frint()
{
cout<<"("<<x<<","<<y<<")"<<endl;
cout<<Circle::area()<<endl;
cout<<CyLinder::area()<<endl;
}
protected:
double height;
};
int main()
{
Point p(2,3);
p.frint();
Circle q(7,6,5);
q.frint();
CyLinder k(10,11,12,14);
k.frint();
return 0;
}