继承
继承的好处:可以减少重复的代码
class A:public B;
A类称为子类 或派生类
B类成为父类 或基类
1.继承的基本语法
#include <iostream>
using namespace std;
class BasePage//公共页面
{
public:
void header()
{
cout<<"首页、公开课、登录、注册"<<endl;
}
void footer()
{
cout<<"帮助中心、交流合作、站内地图"<<endl;
}
void left()
{
cout<<"java,c++,c#"<<endl;
}
};
//java
class Java :public BasePage
{
public :
void content()
{
cout<<"java学科的视频"<<endl;
}
};
//Cpp
class Cpp :public BasePage
{
public :
void content()
{
cout<<"Cpp学科的视频"<<endl;
}
};
void test33()
{
Java ja;
ja.header();
ja.content();
ja.footer();
ja.left();
}
void test34()
{
Cpp c1;
c1.header();
c1.content();
c1.footer();
c1.left();
}
int main()
{
test33();
test34();
}
2.继承方式
公共继承
保护继承
私有继承
#include <iostream>
using namespace std;
//继承方式
//公共继承
class Base1
{
public:
int m_a;
protected:
int m_b;
private:
int m_c;
};
class son1:public Base1
{
public:
void func()
{
m_a=10;//父类中公共权限
m_b=10;//父类中保护权限
//m_c=10;
}
};
//保护继承
class son2: protected Base1
{
void func()
{
m_a=20;
m_b=30;
}
};
//私有继承
class son3 : private Base1
{
void func()
{
m_a=60;
m_b=60;
}
};
void test03()
{
son3 s3;
// s3.m_a=80;
}
void test02()
{
son2 s2;
// s2.m_a=100;
}
void test01()
{
son1 s1;
s1.m_a=100;
//s1.m_b=100;
cout<<s1.m_a<<endl;
}
int main()
{
test01();
}
公共继承:子类继承父类的属性,访问权限和父类中相同,父类私有成员不可访问
保护继承:父类中公共成员变为保护成员,保护成员仍是保护成员,父类私有成员不可访问
私有继承:父类中公共成员和保护成员都变为私有成员,父类私有成员不可访问
3.继承中的对象模型
#include <iostream>
using namespace std;
//继承中的对象模型
class Base1
{
public:
int m_a;
protected:
int m_b;
private:
int m_c;
};
class son:public Base1
{
public:
int m_d;
};
void test04()
{
cout<<"size of son="<<sizeof(son)<<endl;
//父类中所有非静态成员属性都会被子类继承下去
//父类中私有成员属性 是被编译器给隐藏了 因此是访问不到 但确实是被继承下去了
}
int main()
{
test04();
}
4.继承中的构造和析构顺序
父类和子类的构造和析构顺序谁先谁后?
#include <iostream>
//继承中的构造和析构顺序
using namespace std;
class Base
{
public:
Base()
{
cout<<"Base的构造函数"<<endl;
}
~Base()
{
cout<<"Base的析构函数"<<endl;
}
};
class son:public Base
{
public:
son()
{
cout<<"son的构造函数"<<endl;
}
~son()
{
cout<<"son的析构函数"<<endl;
}
};
test01()
{
//Base b;
son s;
}
int main()
{
test01();
}
先有父类构造 之后子类构造和析构 最后是父类析构
5.继承同名成员处理方式
#include <iostream>
//继承中的同名成员处理
using namespace std;
class Base
{
public:
Base()
{
m_a=100;
}
void func()
{
cout<<"BAse-func调用"<<endl;
}
int m_a;
};
class Soner: public Base
{
public:
Soner()
{
m_a=80;
}
void func()
{
cout<<"son-func调用"<<endl;
}
int m_a;
};
void test01()
{
Soner s;
cout<<s.m_a<<endl;//同名时访问的是自身的
cout<<s.Base::m_a<<endl;//需要加一个作用域来访问父类的成员
}
void test02()
{
Soner s1;
s1.func();
//如何调用到父类中的同名成员函数
s1.Base::func();//加作用域
}
int main()
{
//test01();
test02();
}
6.同名静态成员处理方式
和继承同名成员处理方式方法相同
7.继承语法
class 子类:继承方式 父类1,继承方式 父类2…
#include <iostream>
using namespace std;
//多继承语法
class Base1
{
public:
Base1()
{
m_a=100;
}
int m_a;
};
class Base2
{
public:
Base2()
{
m_b=50;
}
int m_b;
};
class son:public Base1, public Base2
{
public:
son()
{
m_c=70;
m_d=90;
}
int m_c;
int m_d;
};
void test01()
{
son s;
cout<<"size of son"<<sizeof(s)<<endl;
}
int main()
{
test01();
}
8.菱形继承
概念:
两个派生类继承同一个基类
又有某个类同时继承这两个派生类
这种继承被称为菱形继承
菱形继承出现的问题:
最后的类继承两个派生类 如果两个派生类中都有同一属性 但是数值不同 我们需要一份即可
#include <iostream>
using namespace std;
class animial
{
public:
int m_Age;
};
//利用虚继承 解决菱形继承的问题 加上关键字virtual
class sheep : virtual public animial
{
};
class tuo: virtual public animial
{
};
class yangtuo:public sheep ,public tuo
{
};
void test01()
{
yangtuo yt;
//yt.m_Age=18;错误
yt.sheep::m_Age=18;
yt.tuo::m_Age=19;
yt.m_Age=60;
cout<<" yt.sheep::m_Age"<< yt.sheep::m_Age<<endl;
cout<<"yt.tuo::m_Age"<< yt.tuo::m_Age<<endl;
cout<<"yt.m_Age"<< yt.m_Age<<endl;
}
int main()
{
test01();
}