1.继承就是面向对象中类与类之间的一种关系,继承的类称为子类、派生类。而被继承的类称为父类、基类或超类。
2.子类继承了父类所有的成员(变量、函数),除了构造、析构、赋值运算符。
3.从基类继承的部分叫做派生类的基类部分。在派生类里,可以添加新的成员函数和数据成员。从父类继承过来的成员和新添加的成员是不一样的。
4.来自父类的私有成员,不能被子类定义的成员函数访问,只能通过来自父类的公有成员函数来访问
5.派生类可以重写基类的函数。
重载和覆盖(重写)的区别及联系?
区别:1.重载(overload)的参数列表必须不同,但覆盖可以;
2.覆盖(overrid)是在继承的时候发生的,而重载包括继承、非继承两种情况。
联系:覆盖是重载的特例,都是在一个类的内部,用不同的方式实现同一个函数。
6.基类的对象或者是指向基类的指针调用基类的函数,派生类的对象或者是指向派生类的指针调用派生类的方法
7.由于派生类继承自基类,一个派生类的对象也可以调用覆盖的方法,在前面加一个父类名和域作用符即可
下面写个例子来演示一下:
#include <iostream.h>
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 子类名 : 访问控制符 父类名
class Derived : public Base //派生类继承基类
{
private:
int d_number;
//int b_number;//自动拥有了来自于父类的成员b_number
public:
// constructor, initializer used to initialize the base part
// of a Derived object.
Derived( int i, int j ):Base(i),d_number(j){ };
//b_number(i)不行, b_number是父类的私有成员。
//在子类中,如何初始化来自于父类的成员变量?
//显式的调用父类的构造函数,把参数传递给父类,
//父类的构造函数用它来初始化父类自己的成员变量。
//如果子类构造函数中调用了父类的构造函数,则先执行的父类的。
// a new member function that overrides(覆盖)
//the print( ) function in Bases
void print( )
{
cout << get_number( ) << " ";
//cout << b_number << " ";//不能执行
// access number through get_number( )
cout << d_number << endl;
}
//int get_number( ) {return b_number;}
};
int main( )
{
Base a(2);
Derived b(3, 4);
cout << "a is ";
a.print( ); // print( ) in Base
cout << "b is ";
b.print( ); // print( ) in Derived
cout << "base part of b is ";
b.Base::print( ); // print( ) in Base
//子类对象调用被子类覆盖了的父类函数。
// Base::print( )这个函数子类也拥有,即子类有两个print函数。
//为了和子类自己定义的print()区别,要加上Base::的前缀。
return 0;
}
继承时,父类的public、 protected、 private成员有什么区别?
对外 : 可以访问、 不可以、 不可以。
对子类: 可直接访问、可直接访问、不可直接访问但可通过父类的公有函数访问。
需要注意的是:
1)父类中成员(变量&函数)的访问范围,在子类中不能被扩大,但可以被缩小。
2)如果是私有(private)继承,则所有继承而来的成员都变成私有的,不管这些成员在父类中是public、protected还是private。
3)子类中从父类继承而来的成员,其访问权限不能大于继承声明时(继承方式中)使用的访问权限修饰符的权限。如果大于其权限,则把子类的成员,缩小到不大于继承方式中访问权限修饰符的水平。