面向对象三大特性
继承
|
public |
protected |
private |
public继承 |
public |
protected |
不可见 |
private继承 |
private |
private |
不可见 |
protected继承 |
protected |
protected |
不可见 |
封装
封装和数据抽象的作用
a.避免类内部出现无意的.可能破坏类对象状态的用户级错误。
b.随着时间推移可以根据需求改变或bug报告来完善类实现,而无须改变用户级代码。
多态
多态要素:基类指针或引用虚函数(一个接口,多种方法)
多态与非多态的实质区别就是函数地址是早绑定还是晚绑定。如果函数的调用,在编译器编译期间就可以确定函数的调用地址,并生产代码,是静态的,就是说地址是早绑定的。而如果函数调用的地址不能在编译器期间确定,需要在运行时才确定,这就属于晚绑定
class father { public: void drink() { cout<<"father drink"<<endl; } virtual void eat() { cout<<"father eat"<<endl; } }; class son:public father { void drink() { cout<<"son drink"<<endl; } virtual void eat()//此处可以不用加virtual也可以,默认就有virtual { cout<<"son eat"<<endl; } }; int main() { father f; son s; father *fptr=&f; fptr->drink(); fptr->eat(); fptr=&s; fptr->drink(); fptr->eat(); }
输出
father drink
father eat
father drink
son eat
重载 重写 覆盖(重定义)
一、重载(overload)
指函数名相同,但是它的参数表列个数或顺序,类型不同。但是不能靠返回类型来判断。
同一层次,同名不同参, virtual和返回值不影响
二、重写(也称为覆盖 override)
是指派生类重新定义基类的虚函数,特征是:
不同层次,同名同参同virtual同返回值,访问修饰符可变
三、重定义(也成隐藏)
不同层次,返回值不影响
参数同,则基类函数被隐藏(区别于重载和重写)
参数异,若基类函数无virtual,基类被隐藏(区别于重写)
class Base { public: virtual void a(int x) { cout << "Base::a(int)" << endl; } // overload the Base::a(int) function virtual void a(double x) { cout << "Base::a(double)" << endl; } virtual void b(int x) { cout << "Base::b(int)" << endl; } void c(int x) { cout << "Base::c(int)" << endl; } }; class Derived : public Base { public: // redefine the Base::a() function void a(complex<double> x) { cout << "Derived::a(complex)" << endl; } // override the Base::b(int) function void b(int x) { cout << "Derived::b(int)" << endl; } // redefine the Base::c() function void c(int x) { cout << "Derived::c(int)" << endl; } };