提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
继承
作用:从基类(父类)基础上建立一1个新的类。继承一些方法,体现了代码复用的思想
已经存在的类称为父类或基类
从父类或基类基础上新建的类称为派生类或子类
#include <iostream>
using namespace std;
class Father{
public:
string first_name="王";
};
class Son:public Father{
};
int main()
{
Son s;
cout<<s.first_name<<endl;
}
结果:
1.透传构造
概念:直接在派生类中的构造函数调用基类的构造函数
#include <iostream>
using namespace std;
class Father{
private:
string first_name;
int age;
public:
Father(string name){
this->first_name=name;
}
Father(string name,int age){
this->first_name=name;
this->age=age;
}
void show(){
cout<<first_name<<" "<<age;
}
};
class Son:public Father{
public:
Son(string name):Father(name){}
Son(string name,int age):Father(name,age){}
};
int main()
{
Son s("张三",18);
s.show();
}
2.委托构造
概念:某个类中的构造函数调用这个类中的重载的构造函数
#include <iostream>
using namespace std;
class Father{
private:
string first_name;
int age;
public:
Father(string name){
cout<<"Father一个参数构造函数"<<endl;
this->first_name=name;
}
Father(string name,int age){
cout<<"Father两个参数构造函数"<<endl;
this->first_name=name;
this->age=age;
}
void show(){
cout<<first_name<<" "<<age<<endl;
}
};
class Son:public Father{
public:
Son(string name):Son(name,18){}
Son(string name,int age):Father(name,age){}
};
int main()
{
Son s("张",20);
s.show();
Son s2("李");
s2.show();
}
3.多重继承
概念:一个派生类它有多个基类,会从多个基类中继承方法
#include <iostream>
using namespace std;
class Sofa{
public:
void sit(){
cout<<"可以坐着";
}
};
class Bed{
public:
void lay(){
cout<<"可以躺着"<<endl;
}
};
class SofaBed:public Sofa,public Bed{
};
int main()
{
SofaBed s;
s.sit();
s.lay();
}
4.多重继承的二义性问题
概念:当多个基类中有同名的成员。此时就会产生二义性
可以通过类名::方法来区分
#include <iostream>
using namespace std;
class Sofa{
public:
void sit(){
cout<<"可以坐着"<<endl;
}
void position(){
cout<<"放在客厅";
}
};
class Bed{
public:
void lay(){
cout<<"可以躺着"<<endl;
}
void position(){
cout<<"放在卧室";
}
};
class SofaBed:public Sofa,public Bed{
};
int main()
{
SofaBed s;
s.sit();
s.lay();
s.Sofa::position();
s.Bed::position();
}
权限
private 本类中可以访问 在子类中不可以访问 全局中不‘’可以访问
protected 本类中可以访问 在子类中可以访问 全局中不可以访问
public 本类中可以访问 在子类中可以访问 全局中也可以访问
#include <iostream>
using namespace std;
class Father{
public:
string first_name="王";
protected:
string car="宝马";
private:
string password="123789";
public:
void show(){
cout<<first_name<<endl;
cout<<car<<endl;
cout<<password<<endl;
}
};
class Son:public Father{
public:
void show2(){
cout<<first_name<<endl;
cout<<car<<endl;
//cout<<password<<endl; //不能访问 父类的私有成员
}
};
int main()
{
Father f;
cout<<f.first_name<<endl;
//cout<<f.car<<endl; //不可以访问
//cout<<f.password<<endl; //不可以访问
Son s;
s.show2();
}
1.public继承
public继承之后 成员在原来基类是什么权限,在派生类中还是什么权限
#include <iostream>
using namespace std;
class Father{
public:
string str1="public";
protected:
string str2="protected";
private:
string str3="private";
};
class Son:public Father{
public:
void show(){
cout<<str1<<endl;
cout<<str2<<endl;
//cout<<str3<<endl;父类私有不能访问
}
};
int main()
{
Son s;
s.show();
}
2.protect继承
protect继承之后。所有继承过来成员都会在Son中变成protected
#include <iostream>
using namespace std;
class Father{
public:
string str1="public";
protected:
string str2="protected";
private:
string str3="private";
};
class Son:protected Father{
public:
void show(){
cout<<str1<<endl;
cout<<str2<<endl;
//cout<<str3<<endl;父类私有不能访问
}
};
class GrandSon:public Son{
public:
void show(){
cout<<str1<<endl;
cout<<str2<<endl;
//cout<<str3<<endl;父类私有不能访问
}
};
int main()
{
Father f;
cout<<f.str1<<endl;
Son s;
cout<<s.str1<<endl; //在子类中变成了protected类型,在全局中不能访问
}
3.private继承
派生类私有继承之后 属性在派生中都变成私有.也就是下方的Son类中的属性都变成私有
#include <iostream>
using namespace std;
class Father{
public:
string str1="public";
protected:
string str2="protected";
private:
string str3="private";
};
class Son:private Father{
public:
void show(){
cout<<str1<<endl;
cout<<str2<<endl;
//cout<<str3<<endl;父类私有不能访问
}
};
class GrandSon:public Son{
public:
void show(){
// cout<<str1<<endl; //因为子类中变成私有 孙子类全访问不到
// cout<<str2<<endl;
}
};
int main()
{
Son s;
s.show();
GrandSon gs;
gs.show();
}
多态
函数重载是静态多态 编译的时候就已经确定
多态就是多种状态,可以一个接口实现多种状态。根据传入对象的不同,虽然调用同样接口,但 选择不同的代码实现。
多态需要三种条件:
1.pubic继承
2.派生类覆盖基类中的虚函数
3.接口参数为基类对象的指针或者基类引,指向派生对象
virtual关键字修饰的函数就是虚函数
1.当函数覆盖成功后,虚函数具有传递性。默认的函数都有virtual关键字
2.成员函数和析构函数可以定义为虚函数。静态函数和构造函数不可以
3.如果声明和定义分离时,virtual关键字只需要加在声明处。
1.多态的实现
#include <iostream>
using namespace std;
class Animal{
public:
virtual void eat(){
cout<<"吃东西"<<endl;
}
};
class Dog:public Animal{
public:
void eat(){
cout<<"吃狗粮"<<endl;
}
};
class Cat:public Animal{
public:
void eat(){
cout<<"吃鱼"<<endl;
}
};
int main()
{
Dog d;
d.eat(); //吃狗粮
Animal * a=&d;
a->eat(); //吃东西
Cat c;
Animal * b=&c;
b->eat(); //吃东西
}
2.多态应用
接口使用多态
#include <iostream>
using namespace std;
class Animal{
public:
virtual void eat(){
cout<<"吃东西"<<endl;
}
};
class Dog:public Animal{
public:
void eat(){
cout<<"吃狗粮"<<endl;
}
};
class Cat:public Animal{
public:
void eat(){
cout<<"吃鱼"<<endl;
}
};
void test1(Animal * a){
a->eat();
}
void test2( Animal &b){
b.eat();
}
int main()
{
//接口调用
Cat c2;
test2(c2);
test1(&c2);
}
抽象类
抽象的概念。只有一些说明,没有具体实现,相当于一个框架的作用。抽象类中不具体的创建对象,不能作为参数类和和返回值类型
一个类中有纯虚函数,这个类就是抽象类;
如果一个类是抽象类,那么一定会有纯虚函数
如果继承了抽象类,需要实现全部实现,才能创建对象。否则它也会成为抽象类
#include <iostream>
using namespace std;
class Shape{
public:
virtual void area()=0;
virtual void perimeter()=0; //面积
};
class Rectangle:public Shape{
public:
void area(){
cout<<"长方形面积"<<endl;
}
void perimeter(){
cout<<"长方形的周长"<<endl;
}
};
int main()
{
Rectangle r;
r.area();
r.perimeter();
}