1.继承方式与权限问题
继承的实质与权限:
实质:父类的数据和成员在子类中也有一份
权限:继承方式只会增强父类属性在子类中的权限显示
public | protected | private | |
protected继承 | protected | protected | 不可直接访问 |
public继承 | public | protected | 不可直接访问 |
private继承 | private | private | 不可直接访问 |
#include <iostream>
using namespace std;
//继承的3种写法
//父类 基类
class parent
{
public:
void printdata()
{
cout << name << endl << age;
}
protected:
string name;
int age;
private:
int A;
};
//子类 派生类
//公有继承
class son1 :public parent
{
public:
void printson1()
{
printdata();
cout << name << endl << age;
// cout << A << endl;//父类中的私有属性不能直接访问,可间接访问
}//继承:父类中的属性在子类中也有一份
protected:
private:
};
//保护继承
class son2 :protected parent//最低权限为保护权限,父类中的public转换为子类中的protected:
{
public:
protected:
private:
};
//私有继承
class son3 :private parent//最低权限为保护权限,父类中的public,protected转换为子类中的private:
{
public:
void print()
{
cout << name << age;
}
protected:
private:
};//私有继承会导致当前父类 无法在孙子类有任何作用
//class子类名:继承方式 父类名
//继承:子类中没有产生新的属性和行为
//派生:派生类中有新的属性和行为产生
int main()
{
son1 son1;
son1.printdata();
son2 son2;
//son2.printdata();不可访问,已转换为protected
son3 son3;
son3.print();
return 0;
}
2.继承中的构造函数
父类中的属性通过父类的构造函数初始化
子类中的构造函数,必须调用父类的构造函数,必须要采用初始化参数列表的写法
单继承:只有一个父类 多继承:两个及两个以上的父类
继承的属性,类一般不会被继承很多层
class Parent
{
public:
Parent()
{
cout << "父类无参构造函数";
}
Parent(string Fname, string Sname) :Fname(Fname), Sname(Sname) {}
protected:
string Fname:
string Sname;
};
class Son1 :public Parent
{
public:
Son1() {} //这种写法,父类中必须存在一个无参的构造函数
Son1(string Fname, string Sname, string Ssname):Parent(Fname,Sname)
{
this->Sfname = Fname;
this->Ssname = Ssname;
}
protected:
string Sfname;
string Ssname;
};
class A
{
public:
A() = default;
A(int A) :a(A)
{
this->a = A;
}
protected:
int a;
};
class B
{
public:
B() = default;
B(int B) :b(B)
{
this->b = B;
}
protected:
int b;
};
class AB:public A,public B
{
public://AB(){}子类想要这种构造函数,每个父类都要有一个无参的构造函数
AB() {}
AB(int ab) :ab(ab)
{
this->ab = ab;
}
protected:
int ab;
};
int main()
{
Son1 son1;//子类构造对象,优先调用父类构造函数
Son1 A("sjkd", "oshd", "skhpd");
AB AB(8);
return 0;
}
3.继承中的同名问题
数据成员同名
成员函数同名
正常赋值同名
class A
{
public:
A(string name, int age) :name(name), age(age) {}
void print()
{
cout << name << endl << age;
}
protected:
string name;
int age;
};
class B:public A
{
public:
B(string name, int age) :A("父类",18),name(name), age(age) {}
void print()
{//就近原则
cout << name << endl << age;
cout << A::name << endl << A::age;
}
protected:
string name;
int age;
};
//虚继承 菱形继承
class AA
{
public:
AA() = default;
AA(int a) :a(a) {}
protected:
int a;
};
class BB:virtual public AA
{
public:
BB(int a, int b) :AA(a), b(a) {}
protected:
int b;
};
class CC :virtual public AA
{
public:
CC(int a, int c) :AA(a), c(c) {}
protected:
int c;
};
class DD :public BB, public CC
{
public://菱形继承,必须调用祖父的构造函数
DD() :BB(1, 2), CC(3, 4) {}
protected:
};
int main()
{
B b("lskfn", 18);
b.print();
//正常的指针调用
B* pB = new B("kjsbd", 18);
pB->print();
A* pA = new A("lknfsl", 18);
pA->print();
//非正常
//允许子类对象初始化父类指针
A* PA = new B("lksfn", 20);
PA->print();//父类
//在没有virtual情况下 看指针类型
//在有virtual情况下 看赋值对象
//父类对象初始化子类指针,不安全,不要这样操作
return 0;
}
4.构造顺序问题
单继承:先构造父类再构造子类,析构顺序相反
多继承:任何构造顺序问题都和初始化参数列表无关
class A
{
public:
A() { cout << "A"; }
~A() {}
protected:
};
class B:public A
{
public:
B() { cout << "B"; }
protected:
};
class C {
public:
C() { cout << "C"; }
~C() { cout << "C"; }
};
class D
{
public:
D() { cout << "D"; }
~D() { cout << "D"; }
};
class E :public C, public A, public D
{
public:
E() { cout << "E"; }
~E() { cout << "E"; }
};
int main()
{
//B B;//输出ABBA
E E;//输出CADFFDAC
return 0;
}
HOMEWORK:
#define PI 3.14
class Shape
{
public:
int width = 10;
int heigth = 10;
int radius = 10;
};
class Rect:public Shape
{
public:
void RprintS()
{
cout << "矩形的面积是" << width * heigth << endl;
}
void RprintC()
{
cout << "矩形的周长是" << (width + heigth) * 2 << endl;
}
protected:
};
class Circle :public Shape
{
public:
void CprintS()
{
cout << "圆形的面积是" << PI*radius*radius << endl;
}
void CprintC()
{
cout << "圆形的周长是" << 2*PI*radius << endl;
}
protected:
};
int main()
{
Rect R;
R.RprintC();
R.RprintS();
Circle C;
C.CprintC();
C.CprintS();
return 0;
}