(一)、什么是继承与派生
(1).继承是自然界一个普遍的重要特性,源于人们对客观世界的认识。(狗和黑狗的特性)一般到特殊的关系.
(2).继承机制,就是在一个已存在的类(父类)的基础上建立一个新的类,这个新的类**(子类)自动拥有已有类的全部成员的一种机制**,进而体现出层次性.(下层是上层的特殊类)
(3).继承是类之间定义的一种重要关系,已有类A的基础上定义类B,类B会自动得到类A的函数成员和数据成员,使得程序员只需在类B定义类A中所没有的新成分就柯完成在类B的定义,
在这种情况下,就称类B继承了类A,类A派生了类B,A是基类(父类),B是派生类(子类),这种机制叫做继承
(二)、为什么要使用继承和派生?
类的继承和派生机制使程序员无需修改已有的类,只需在既有类的基础上,根据问题的实际需要,通过增加部分代码或修改少量代码而得到的新的类(派生类),从而解决了程序代码的重用问题.
(三)、继承方式
公有继承,私有继承,保护继承,
如果缺省:就是声明的时候继承方式是空的,那就默认为是按照私有继承方式继承.
(四)、继承的属性
(1).继承基类的成员函数和数据成员
(2).增加新的数据成员和成员函数.
(3).重载或重新定义继承自基类的成员函数
(4).改变基类成员在派生类中的访问属性
1.添加新的数据成员和成员函数
#include <iostream>
using namespace std;
class Base
{
private:
int x;
public:
void setX(int i)
{
x=i;
}
void show()
{
cout<<"x="<<x<<endl;
}
};
class Drevid: public Base
{
public:
void show1() //添加成员函数
{
cout<<"LWT love Lwt"<<endl;
}
};
int main()
{
Base b;
b.setX(10);
b.show();
Drevid d;
d.setX(20); // 改变成员
d.show(); //继承成员
d.show1();
return 0;
}
2.覆盖改变成员
#include <iostream>
using namespace std;
class Base //基类
{
private:
int x;
public:
void setX(int i)
{
x=i;
}
void show()
{
cout<<"x="<<x<<endl;
}
};
class Drevid: public Base
public:
void show1()
{
cout<<"我喜欢!"<<endl;
}
void show()
{
cout<<"喜欢我!"<<endl;
}
};
int main()
{
Base b;
b.setX(10);
b.show();
Drevid d;
d.setX(20);
d.show(); //覆盖
d.show1();
return 0;
(五)、继承方式和派生类的访问权限
(1).公有继承(公私保变公私保)
最常见的继承方式,基类的public成员仍然作为派生类的public成员;基类中的privat成员被隐藏(使得派生类内部也变得不可以直接访问私有成员)。虽然不能够直接访问基类的private成员,但可通过从基类的公有成员访问。派生类的对象可以访问基类中的非private成员;
派生类的对象只能访问基类中的public成员
(2).保护继承(公私保全变保)
在派生类的内部,基类的公有成员和保护成员均作为派生类的保护成员,派生类的成员可以直接访问它们,而派生类的成员无法访问基类的私有成员。
保护继承时基类中各成员属性均变为protected,并且基类中private成员被隐藏。派生类的成员只能访问基类中的public/protected成员,而不能访问private成员;派生类的对象不能访问基类中的任何的成员。
1.本类内部: 可以访问基类的public/private
2.本类的对象: 不能访问基类的任何成员
3.本类的派生类内部: 可以访问基类的public/private
4.本类的派生类对象: 不能访问基类的任何成员
在派生类的外部:派生类的成员和派生类的对象均无法访问基类的全部成员
如果基类只进行了一次派生,则保护继承和私有继承的功能完全相同,但保护继承可以进一步派生,而私有继承则不可以.
(3).私有继承:(公私保变私)
基类中的private被隐藏,在派生类的内部,基类的公有成员和保护成员作为派生类的私有成员,派生类的成员可以直接访问基类中(公有和保护),而派生类的对象无法访问基类的任何成员
私有继承之后,全部基类成员在派生类中都成为了私有成员或不可访问的成员,进一步派生后,将再也无法直接访问
派生类对象不能访问基类中的任何的成员函数
(六)各种实列
1.【公有继承下派生类通过公有成员访问私有成员】
#include <iostream>
using namespace std;
class Base
{
private:
int x;
public:
void setX(int i)
{
x=i;
}
void show()
{
cout<<"x="<<x<<endl;
}
int getX() //共有返回私有
{
return x;
}
};
class Drevid: public Base
{
public:
void display()
{
cout<<"x="<< getX()<<endl; //访问基类中的私有
}
};
int main()
{
Base b;
b.setX(10);
b.show();
Drevid d;
d.setX(20);
d.display();
return 0;
}
2.【公有继承下派生类通过公有成员访问保护成员】
#include <iostream>
using namespace std;
class Base
{
protected: //保护
int x;
public:
void setX(int i)
{
x = i;
}
void show()
{
cout << "x=" << x << endl;
}
int getX() //共有返回保护
{
return x;
}
};
class Drevid : public Base
{
public:
void display()
{
cout << "x=" << getX() << endl; //访问基类中的保护
}
};
int main()
{
Base b;
b.setX(10);
b.show();
Drevid d;
d.setX(20);
d.display();
return 0;
}
3.【私有继承下类外不能访问基类的所有成员】
#include <iostream>
using namespace std;
class Base
{
private:
int y;
protected:
int x;
public:
void setX(int i)
{
x=i;
}
void show()
{
cout<<"x="<<x<<endl;
}
};
class Drevid: private Base //私有继承访问
{
public:
void show1()
{
cout<<"我的名字:"<<endl;
}
};
int main()
{
Base b;
b.setX(10);
b.show();
Drevid d;
// d.setX(20); //会报错,因为现在基类的公有成员被私有成员访问,所以...
// d.show(); //会报错,因为现在基类的公有成员被私有成员访问,所以...
return 0;
}
4.【私有继承下访问基类的私有数据成员】
#include <iostream>
using namespace std;
class Base
{
private:
int y;
protected:
int x;
public:
void setY()
{
cout << "结果为:y=" << 10 << endl;
}
void setX(int i)
{
x = i;
}
void show()
{
cout << "x=" << x << endl;
}
int getX()
{
return x;
}
};
class Drevid : private Base
{
public:
void show1()
{
setY(); //会变成私有
}
};
int main()
{
Base b;
b.setX(10);
b.show();
Drevid d;
d.show1(); //派生类可以访问派生类
return 0;
}
5.【私有继承下进一步派生】
#include <iostream>
using namespace std;
class Base
{
private:
int y;
protected:
int x;
void setY()
{
y=10;
}
public:
void setX(int i)
{
x=i;
}
void show()
{
cout<<"x="<<x<<endl;
}
int getX()
{
return x;
}
};
class Drevid: private Base
{
public:
void show1()
{
setY(); //基类中的保护会员变成私有成员
}
};
class DDrevid: public Drevid //用公有继承的方式进一步派生后
{
public:
void f()
{
// setY(); 报错 //进一步派生后,仍然还是私有成员
}
};
int main()
{
Base b;
b.setX(10);
b.show();
Drevid d;
// d.setY(); 报错 //这个已经变成派生类的私有成员,在类外不能访问.
d.show1();
DDrevid d1;
d1.f(); //进一步派生后,仍然无法访问
return 0;
}
6.【保护继承进一步派生】
#include <iostream>
using namespace std;
class Base
{
private:
int y;
protected:
int x;
void setY()
{
y = 10;
}
public:
void setX(int i)
{
x = i;
}
void show()
{
cout << "x=" << x << endl;
}
int getX()
{
return x;
}
};
class Drevid : protected Base
{
public:
void show1()
{
setY(); //基类中的保护成员会变成保护成员
}
};
class DDrevid : public Drevid
{
public:
void f()
{
setY(); //进一步派生后,公有继承下仍然是保护成员
}
};
int main()
{
Base b;
b.setX(10);
b.show();
Drevid d;
// d.setY(); 报错 //这个已经变成派生类的保护成员,在类外不能访问.
d.show1();
DDrevid d1;
d1.f(); //可以访问
return 0;
}
(七)、派生类的构造函数
1.什么是派生类的构造函数:
1.派生类的数据成员既包括从基类继承的数据成员,也包括派生类新增的数据成员,甚至还可能包括派生类内定义的内嵌成员对象.
2.派生类构造函数在对派生类对象进行初始化时需要对基类数据成员,新增数据成员和内嵌对象成员进行初始化.
3.派生类会继承除基类构造函数外的所有基类成员,也就是说,(派生类是不能继承基类的构造函数的!!!)
4.在定义派生类的构造函数时除了对自己的数据成员进行初始化外,还必须借助派生类的构造函数,调用基类的构造函数,从而结组基类的构造函数,从而借助基类的构造函数,来初始化从基类继承的数据成员.
5.如果派生类拥有对象成员时,派生类的构造函数还拥有对象成员所属类构造函数,来初始化这个对象成员.
2.派生类构造函数的格式(构造函数先基再派,析构函数先派后基)
(2).派生类的构造函数的定义格式:
派生类名::派生类名(): 类名(),内嵌对象成员名1…
{
派生类新增成员的初始化
}
(3).当基类中没有显示定义构造函数时,派生类的构造函数定义可以省略,系统采用默认的构造函数
(4).当基类定义了具有形参的构造函数时,派生类很可能也需要显示定义构造函数,提供将参数传递给基类构造函数的途径,使基类对象在初始化时可以获取相关数据,在某些情况下,派生类构造函数的函数体可能为空,仅起参数产地及调用基类与内嵌对象构造函数的作用
(5).派生类定义构造函数会自动调用基类构造函数
3.实列(派生类构造函数的初始化)
代码展示:
#include <iostream>
using namespace std;
class Inner
{
private:
int y;
public:
Inner(int b)
{
y=b;
cout<<"inner的构造函数:"<<y<<endl;
}
};
class Base
{
protected:
int x;
public:
Base(int a)
{
x=a;
cout<<"基类的构造函数:"<<x<<endl;
}
};
class Derived: public Base
{
private:
Inner i;
int z;
public:
Derived(int a,int b,int c):Base(a),i(b) //派生类构造函数,有内嵌,加派生类新增
{
z=c;
cout<<"派生类的构造函数:"<<z<<endl;
}
};
int main()
{
Base b(100);
cout<<"*************************************"<<endl;
Derived d(10,20,30); //+++++++++++++++
return 0;
}
如有不解,随时支持私聊!!!!!