继承语法:
class 子类 :继承方式 父类
为什么继承:简化代码,避免重复代码过多,提高代码可读性。
#include<bits/stdc++.h>
using namespace std;
class Basepage {
public :
void mainpage(){
cout<<"mainpage,public class,signin ,signout"<<endl;
}
void bottompage() {
cout<<"help,map,....."<<endl;
}
void content(){
cout<<"tyep vedio"<<endl;
}
void list(){
cout<<"Java,Python,C++....."<<endl;
}
};
class Java :public Basepage{
public:
void content(){
cout<<"Java vedio"<<endl;
}
};
void test01(){
Java ja;
ja.mainpage();
ja.bottompage();
ja.content();
ja.list();
return ;
}
signed main(){
test01();
return 0;
}
三种继承方式:
1.公共继承
2.保护继承
3.私有继承
特点:
父类的私有对象,子类无论采取何种继承方式都无法并访问。
父类中的私有对象都其实都已经被子类继承了,但是被编译器自动识别并隐藏了隐藏了
父类中的公共权限对象经子类公共继承后变成子类的公共权限对象
父类中的保护权限对象经过子类继承后变成子类的保护权限对象
父类中的公共权限对象经子类保护继承后变成子类的保护对象
父类中的保护权限对象经过子类的保护继承后变成子类的保护对象
父类中的公共权限对象经子类私有继承后变成子类的私有对象
父类中的保护权限对象经过子类的私有继承后变成子类的私有对象
#include<bits/stdc++.h>
using namespace std;
class base {
public :
int m_a;
protected :
int m_b;
private :
int m_c;
};
class son1:public base{
public:
void func(){
m_a=10;//父类中的公共权限到子类中依然是公共权限
m_b=10;//父类中的保护权限到子类中依然是保护权限
//m_c=1000;公共继承类中的私有权限子类无法访问
}
};
class son2:protected base{
public:
void func(){
m_a=100;//父类中的公共权限内容到子类中变为保护权限
m_b=1000;//父类中的保护权限内容到子类中变为保护权限
// m_c=10000; m_c=1000;尽管是保护继承,父类中的私有权限子类无法访问
}
};
void test01(){
son1 s;
s.m_a=100;
// s.m_b=100;//保护权限,类外不可访问,间接证明父类中的保护权限到子类中依然是保护权限
// s.m_c=100;//证明公共继承类中的私有权限子类无法访问
}
void test02(){
son2 s;
// s.m_a=100;保护权限,类外不可访问
// s.m_b=100;保护权限,类外不可访问
// s.m_c=100;私有权限子类无法继承并访问
}
class son3:private base{
public:
void func(){
m_a=100;//父类中的公共权限内容到子类中变为私有权限
m_b=100;//父类中的公共权限内容到子类中变为私有权限
// m_c=100;父类中隐私内容,子类无法访问到
}
};
void test03(){
son3 s;
// s.m_a=100;都变为私有无法访问
// s.m_b=100;
// s.m_c=100;
}
class granson:public son3{
public:
void func(){
//孙子的父类是son3,son3私有继承base 对象都变成了私有,孙子无法访问
// m_a=100;
// m_b=100;
// m_c=100;
}
};
signed main(){
test01();
return 0;
}
继承中同名变量和同名函数的处理。
加上作用域:s.Base::m_a 同名变量
s.Base::func() 同名函数
#include<bits/stdc++.h>
using namespace std;
class Base{
public:
int m_a;
int m_b;
Base(){
m_a=100;
}
void func(){
cout<<"base -> func->run"<<endl;
}
};
class Person:public Base{
public:
int m_a;
int m_b;
Person(){
m_a=1000;
}
void func(){
cout<<"person ->func ->run"<<endl;
}
};
void test01(){
Person s;
cout<<s.m_a<<endl;
s.func();
s.Base::func();
cout<<s.Base::m_a<<endl;
}
signed main(){
test01();
return 0;
}
继承中同名静态成员变量与静态成员函数的处理
一旦子类与父类出现了同名的静态的成员函数,那么父类所有同名函数都会被隐藏,只有加作用域才能访问。
静态成员变量和静态成员函数的访问需要外加作用域
静态成员函数的两种访问方式:
1.通过对象访问。
2.通过类名访问。(不能从父类访问子类)
#include<bits/stdc++.h>
using namespace std;
class Base{
public:
static int m_a;
static void func(){
cout<<"Base->func->run"<<endl;
}
};
int Base::m_a=100;
class son:public Base{
public:
static int m_a;
static void func(){
cout<<"son->func->run"<<endl;
}
};
int son::m_a=1200;
void test01(){
son s;
// 1.通过对象访问数据
cout<<s.Base::m_a<<endl;
cout<<s.son::m_a<<endl;
s.func();
s.Base::func();
// 2.通过类名来访问数据
cout<<son::m_a<<endl;
cout<<son::Base::m_a<<endl;//第一个:表示通过类名的方式,第二个表示通过对象访问
Base::func();
son::func();
son::Base::func();
// Base::son::func();只能通过儿子访问父亲
}
signed main(){
test01();
return 0;
}
C++ 中的多继承语法
多继承中可能会引发同名成员函数得出想,需要加作用域区分,在工程中一般不适用。
#include<bits/stdc++.h>
using namespace std;
class Base1{
public:
int m_a;
Base1(){
m_a=200;
}
};
class Base2{
public:
int m_a;
Base2(){
m_a=100;
}
};
class son:public Base1,public Base2{
public:
int m_c;
int m_d;
int m_a;
int m_b;
};
void test01(){
son s;
cout<<s.Base1::m_a<<endl;
cout<<s.Base2::m_a<<endl;
// cout<<s.m_a<<endl;必须加作用于区分
}
signed main(){
test01();
return 0;
}
菱形继承:
两个派生类继承同一个基类,又有某个类同时继承这两个派生类,这种继承叫做菱形继承或钻石继承
当出现菱形继承是,当两个父类拥有共同数据是,需要佳作用于区分。
//这份数据只需要一份就可以了,菱形继承浪费了空间。