继承
#include<iostream>
using namespace std;
//继承语法: class 子类:继承方式 父类
//如果是public继承:公共和保护权限同父类,私有不可访问。 protected继承:父类的公共权限和保护权限再子类中均是保护权限,私有不可访问
//private访问:父类中公共和保护权限均变为私有,父类私有不可访问
//普通页面
class BasePage{
public:
void header(){
cout<<"首页、公开课..."<<endl;
}
void footer(){
cout<<"帮助中心、交流合作"<<endl;
}
void left(){
cout<<"Java、C++、Python"<<endl;
}
};
//Java页面
class Java:public BasePage{
public:
void content(){
cout<<"Java学科视频"<<endl;
}
};
//Python页面
class Python:public BasePage{
public:
void content(){
cout<<"Python学科视频"<<endl;
}
};
//继承中同名处理方式
class Base{
public:
Base(){
m_A=100;
}
void func(){
cout<<"Base func调用"<<endl;
}
int m_A;
static int m_B;
};
int Base::m_B=100;
class Son:public Base{
public:
Son(){
m_A=200;
}
void func(){
cout<<"Son func调用"<<endl;
}
int m_A;
static int m_B;
};
int Son::m_B=200;
//多继承
class Base1{
public:
Base1(){
m_A=100;
}
int m_A;
};
class Base2{
public:
Base2(){
m_A=200;
}
int m_A;
};
//多继承语法
class newSon:public Base1,public Base2{
public:
newSon(){
m_C=300;
m_D=400;
}
int m_C;
int m_D;
};
//菱形继承
//动物类
class Animal{
public:
int m_Age;
};
//羊类
class Sheep:virtual public Animal{ //在继承前加关键字变虚继承,因为年龄数据只有一份即可,这里有两个,所以用虚继承讲将其变成一个
};
//驼类
class Camel:virtual public Animal{
};
//羊驼类
class SheepCamel:public Sheep,public Camel{
};
int main(){
Java java;
java.content();
Python python;
python.content();
Son s;
cout<<s.m_A<<endl;//200
//通过子类对象访问父类的同名成员,需要加作用域
cout<<s.Base::m_A<<endl;//100
s.func();//子类成员
s.Base::func();//通过子类调用父类成员函数
//注意:只要子类出现同名函数,就会隐藏掉所有父类的同名函数,包括重载,需要加作用域
//同名静态成员
cout<<s.m_B<<endl;//200
cout<<s.Base::m_B<<endl;//100
//或者通过类名访问
cout<<Son::m_B<<endl;
cout<<Son::Base::m_B<<endl;
//静态成员方法同理
//多继承
newSon new_son;
cout<<new_son.Base1::m_A<<endl;//两个父类间出现相同成员名,要标明作用域
cout<<new_son.Base2::m_A<<endl;
SheepCamel sc;
sc.Sheep::m_Age=20;
sc.Camel::m_Age=30;
//当菱形继承的时候,两个父类有相同的数据,加作用域进行区分
cout<<sc.m_Age<<endl;//30
cout<<sc.Sheep::m_Age<<endl;//30
return 0;
}
多态
#include<iostream>
#include<string>
using namespace std;
//多态
class Animal{
public:
//变成虚函数
virtual void speak(){
cout<<"说话"<<endl;
}
};
class Cat:public Animal{
public:
void speak(){
cout<<"喵"<<endl;
}
};
//执行说话函数
//地址早绑定,在编译阶段就确定了函数地址
void doSpeak(Animal &animal){//想执行猫的函数需要变成虚函数
animal.speak();
}
//总结:多态首先得有继承关系,其次子类要重写父类的虚函数
//案例:计算器
class AbstractCalc{
public:
virtual int getResult(){
return 0;
}
int m_Num1;
int m_Num2;
};
//加法
class AddCalc:public AbstractCalc{
public:
int getResult(){
return m_Num1+m_Num2;
}
};
//减法
class SubCalc:public AbstractCalc{
public:
int getResult(){
return m_Num1-m_Num2;
}
};
//乘法
class MulCalc:public AbstractCalc{
public:
int getResult(){
return m_Num1*m_Num2;
}
};
//除法
class DivCalc:public AbstractCalc{
public:
int getResult(){
return m_Num1/m_Num2;
}
};
//纯虚函数
class Base{
public:
virtual void fun()=0;//在虚函数的基础上=0,因为发现以前虚函数体用不上
//有纯虚函数的类叫抽象类,无法实例化.且抽象类的子类要重写纯虚函数,不然也是抽象类
};
class Son:public Base{
public:
virtual void fun(){
cout<<"纯虚函数重写"<<endl;
}
};
//虚析构
class Big{
public:
Big(){
cout<<"Big构造函数"<<endl;
}
virtual ~Big(){//虚析构:解决了释放问题
cout<<"Big析构函数"<<endl;
}
virtual void speak()=0;
};
class Small:public Big{
public:
Small(string name){
cout<<"Small构造函数"<<endl;
m_Name=new string(name);
}
~Small(){
if(m_Name!=NULL){
cout<<"Small析构函数"<<endl;
delete m_Name;
m_Name=NULL;
}
}
virtual void speak(){
cout<<*m_Name<<"说话"<<endl;
}
string *m_Name;
};
int main(){
Cat cat;
doSpeak(cat);
//计算器测试
//多态实现:父类指针或引用指向子类对象
AbstractCalc *abc=new AddCalc;
abc->m_Num1=10;
abc->m_Num2=10;
cout<<abc->getResult()<<endl;
delete abc;
//纯虚函数
Base *base=new Son;
base->fun();
//注意到一个问题,多态时父类指针不会调用子类中析构函数,导致子类如果有堆区数据会泄露
//所以引入虚析构
Big *big=new Small("Tom");
big->speak();
delete big;//在释放堆区空间时不会执行子类的析构函数
//虚析构解决
return 0;
}