1 继承权限
1.1 继承写法
class 子类:继承方式 父类名
{
};
1.2 三种继承方式
共有继承 public: 父类中原来是什么属性,继承后在子类中还是原来的属性
保护继承 protected: 父类中原来的公有属性在子类中变为保护属性,其余不变
私有继承 private: 父类中的属性在子类全部变为私有属性
//父类 (基类)
class parent
{
public:
protected:
private:
};
//子类 (派生类)
class son1:public parent
{
public:
protected:
private:
};
class son2 :protected parent
{
public:
protected:
private:
};
class son3 :private parent
{
public:
protected:
private:
};
1.3 继承的实质:父类中的数据和 成员 子类中有一份
权限问题 :继承方式只会加强父类属性在子类中的权限显示。
父类public | 父类protected | 父类ptivate | |
public 继承 | public | protected | ptivate (可继承但不可直接访问) |
protected 继承 | protected | protected | ptivate(可继承但不可直接访问) |
ptivate 继承 | ptivate | ptivate | ptivate(可继承但不可直接访问) |
注: 这里的访问是指在 父类的私有属性不能直接访问。
私有继承会导致当前父类中的成员和属性 在 孙子类中不起作用
#include<iostream>
using namespace std;
//父类 (基类)
class parent
{
public:
int a;
void printParent() {}
int& getdata()
{
return c;
}
protected:
int b;
private:
int c;
};
//子类 (派生类)
class son1:public parent
{
public:
//int a;
void printson1()
{
cout << a << b << endl;
printParent();
//cout << c << endl; //c在父类中是私有属性,继承只是不可直接访问
//如提供接口(如第9行代码) 可以间接访问
}
protected:
//int b;
private:
// int c;
};
class son2 :protected parent
{
public:
protected:
void printson2()
{
cout << a << b << endl;
//cout << c << endl; //不可直接访问
}
//int a;
//int b;
private:
// int c;
};
class son3 :private parent
{
public:
void printson3()
{
cout << a << endl; //可直接访问
a = 23;
//cout << c << endl; //父类中私有属性不直接可访问
}
protected:
private:
//int a; //私有继承 继承后全部变为私有属性
//int b;
//int c;
};
//girl 是孙子辈继承, 在son3类里 属性全部变为私有,导致在girl中无法访问
class girl :public son3
{
public:
//cout << a << endl;
};
int main()
{
son1 boy1;
boy1.getdata();
boy1.printParent();
son2 boy2;
//boy2.printson2(); //son2 保护继承 不能访问非公有属性和成员
}
1.4 继承与派生
继承: 子类中没有产生新的属性或者行为
派生:派生类中有新的属性和行为产生
2 继承中构造函数
2.1 父类的属性通过父类的构造函数初始化
子类中的构造函数,必须要调用父类构造函数,必须采用初始化参数列表的方式
子类要用无参构造,则父类中必须存在无参构造或参数缺省
#include<iostream>
using namespace std;
class A
{
public:
A() { cout << "父类中的无参构造函数"<<endl; }
A(string FName,string SName):FName(FName),SName(SName){}
protected:
string FName;
string SName;
};
class B :public A
{
public:
//这种无参构造 要求父类必须存在无参构造函数,缺省也可
B() { cout << "子类中的无参构造" << endl; }
//父类的属性在子类中必须采用初始化参数列表的方式,必须调用父类构造函数,
//子类自身的属性采用哪种方式初始化,都可以的
B(string FName, string SName, string sonSName) :A(FName, SName)
{
this->sonFName = FName;
this->sonSName = sonSName;
}
void print()
{
cout << "父:" << FName + SName << endl;
cout << "子:" << sonFName + sonSName << endl;
}
protected:
string sonFName;
string sonSName;
//string FName;
//string SName;
};
int main()
{
B son; //子类构造对象,优先调用父类的构造函数
B girl("上官","飞雪","夏丹");
girl.print();
return 0;
}
2.2 单继承和多继承
单继承: 只有一个父类
多继承: 两个或者两个以上的父类
#include<iostream>
using namespace std;
class MM
{
public:
MM() { cout << "MM中的无参构造函数" << endl; }
MM(string mmFName, string mmSName) :mmFName(mmFName), mmSName(mmSName) {}
protected:
string mmFName;
string mmSName;
};
class GG
{
public:
GG() { cout << "GG中的无参构造函数" << endl; }
GG(string ggFName, string ggSName) :ggFName(ggFName), ggSName(ggSName) {}
protected:
string ggFName;
string ggSName;
};
class son :public MM, public GG
{
public:
//这种无参构造 要求父类必须存在无参构造函数,缺省也可
son() { cout << "子类中的无参构造" << endl; }
//父类的属性在子类中必须采用初始化参数列表的方式,必须调用父类构造函数,
//子类自身的属性采用哪种方式初始化,都可以的
son(string mmFName, string mmSName, string ggFName,string ggSName) :MM(mmFName, mmSName),GG(ggFName,ggSName)
{
this->sonFName = mmFName+ggFName;
this->sonSName = mmSName+ggSName;
}
void print()
{
cout << "子 名字:" << sonFName + sonSName << endl;
}
protected:
string sonFName;
string sonSName;
//string mmFName;
//string mmSName;
//string ggFName;
//string ggSName;
};
int main()
{
son boy; //子类构造对象,优先调用父类的构造函数
son girl("上官", "飞雪", "夏丹","浩天");
girl.print();
return 0;
}
2.3 继承的属性,无论被继承多少次,所以类一般不会被继承很多层,会导致类的臃肿
class B:public A
{
public:
B(int a,int b) :A(a),b(b) {}
int b;
};
class C :public B
{
public:
C(int a, int b,int c) :B(a,b),c(c) {}
int c;
};
class D :public C
{
public:
D(int a, int b, int c,int d) :C(a,b,c), d(d) {}
int d;
};
3 继承中的同名问题
不做特殊处理 就近原则
指定输出 需要类名限定
4 虚继承(菱形继承)
祖类A 父类BC分别继承A,D继承BC 此时D存在两份A的属性,为了决定是由谁决定,引入虚继承, 父类BC必须采用 virtual修饰 D构造函数中的A类属性必须有 祖父A决定
#include<iostream>
using namespace std;
class A
{
public:
A(int a) :a(a) {}
protected:
int a;
};
class B:virtual public A
{
public:
B(int a,int b) :A(a),b(b) {}
protected:
int b;
};
class C :virtual public A
{
public:
C(int a, int b) :A(a), c(c) {}
protected:
int c;
};
class D :public B, public C
{
public:
//菱形继承 必须调用祖父类的构造函数
D() :B(1, 2), C(3, 4), A(666) {}
void print()
{
cout << a<< endl;
cout << A::a << endl;
cout << B::a << endl;
cout << C::a << endl;
}
protected:
int d;
};
int main()
{
D d;
d.print();
return 0;
}
5 单继承中的构造顺序问题
先构造父类的在构造子类的,析构顺序相反
多继承中构造顺序问题
任何构造顺序问题都和初始化参数列表无关
构造顺序和继承顺序一致
#include<iostream>
using namespace std;
class A
{
public:
A() { cout<<"A的构造" << endl; }
~A() { cout << "A的析构" << endl; }
};
//单继承
class B :public A
{
public:
B() { cout << "B的构造" << endl; }
~B() { cout << "B的析构" << endl; }
};
class C
{
public:
C() { cout << "C的构造" << endl; }
~C() { cout << "C的析构" << endl; }
};
class D
{
public:
D() { cout << "D的构造" << endl; }
~D() { cout << "D的析构" << endl; }
};
//多继承 构造顺序和继承顺序一致
class F :public D,public C,public A
{
public:
F() { cout << "F的构造" << endl; }
~F() { cout << "F的析构" << endl; }
};
int main()
{
{
B b; //ABBA
}
cout << endl;
F f; //dcaffacd
return 0;
}
以下是自己尝试写简单功能
#include<iostream>
using namespace std;
#define PI 3
class Shape
{
public:
Shape(int x=0, int y=0,int r = 0 ) {}
protected:
int r;
int x;
int y;
};
class Circle :public Shape
{
public:
Circle( int r ):Shape(r)
{
this->c_r = r;
}
void printL()
{
cout << "周长为:" << 2 * PI * c_r << endl;
}
void printS()
{
cout << "面积为" << PI * c_r * c_r << endl;
}
protected:
int c_r;
};
class Rect :public Shape
{
public:
Rect(int x,int y):Shape(x,y)
{
this->r_x = x;
this ->r_y = y;
}
void printL()
{
cout << "周长为:" << 2 * (r_x + r_y) << endl;
}
void printS()
{
cout << "面积为" << r_x * r_y << endl;
}
protected:
int r_x;
int r_y;
};
class Teach
{
public:
Teach(string TName,string Ttitle):TName(TName),Ttitle(Ttitle) {}
protected:
string TName;
string Ttitle; //职称
};
class Stu
{
public:
Stu(int cla, string num) :cla(cla), num(num) {}
protected:
int cla; //年级
string num; //学号
};
class PosStu:public Teach,public Stu
{
public:
PosStu(string Pos_name, int cla, string num, string TName, string Ttitle)
:Stu(cla, num), Teach(TName, Ttitle)
{
this->Pos_name = Pos_name;
}
void print()
{
cout << "学生姓名:" << Pos_name << "\t" << "学生年级:" << cla<< "\t" << "学生学号:" << num << "\t"<< "教师名字:" << TName << "\t"<< "教师职称:" << Ttitle << endl;
}
protected:
string Pos_name; //学生姓名
int Pos_cla; //学生年级
string Pos_num; //学生学号
string Pos_TName; //教师名字
string Pos_Ttitle; //教师职称
};
int main()
{
cout << "圆形" << endl;
Circle c1(3);
c1.printL();
c1.printS();
cout << "矩形" << endl;
Rect t1(5,6);
t1.printL();
t1.printS();
PosStu p1 ("小六",5,"12345","阿达","讲师");
p1.print();
return 0;
}