//Object – Oriented 8 – 1 Inheritance grammar
//继承的语法
#include <iostream>
using namespace std;
//你可以把继承理解成 数据结构中的一颗树
/*
动物
/ \
猫 狗
*/
/*
继承的语法
class 子类 : 继承方式 父类{}
子类 -> 派生类
父类 -> 基类
写了两个类 发现他们有一些共性 把共性抽出来实现一个新的类 那两个类成为新类的派生类 这样能省掉一些冗余代码
*/
class Animal {
public:
void eat() {
cout << “吃” << endl;
}
};
class Cat : public Animal {
//类 类名: public 继承的类
public:
/*void eat() {
cout << “吃” << endl;
}*/
void sayHi() {
cout << “喵喵~” << endl;
}
};
class Dog : public Animal {
public:
/*void eat() {
cout << “吃” << endl;
}*///放动物类
void sayHi() {
cout << “汪汪汪~” << endl;
}
};
int main() {
Cat c;
Dog d;
c.eat();
d.eat();
c.sayHi();
d.sayHi();
return 0;
}
//Object – Oriented 8 – 2 Inheritance Mode
//继承方式
#include <iostream>
using namespace std;
/*
* 继承方式
公共 public
保护 protected
私有 private
继承方式有三种 访问权限也有三种 组合一下 就是 3*3=9种
class 子类名 : 继承方式 父类名{};
上面代表父类访问权限
下面代表子类继承方式
| public | protected | private |
| public | public | protected | 无法访问 |
| protected | protected | protected | 无法访问 |
| private | private | private | 无法访问 |
public:类内可以访问,类外也可以访问
protected:类内可以访问,类外也可以访问,且子类可以访问
private:类内可以访问,类外不可访问,且子类不可访问
*/
class Animal {
public:
int m_pub;
protected:
int m_pro;
private:
int m_pri;
};
class Cat : public Animal {
public:
Cat() {
m_pub = 1;
m_pro = 2;
//m_pri = 3;//父类私有成员,子类公有继承,无法访问
}
};
class BossCat : public Cat {
public:
BossCat() {
m_pub = 1;
m_pro = 2;//爷爷类的保护成员 父类的保护成员,子类还是保护成员 再继承一次发现类内可以访问 所以不是 是保护保护
//m_pri = 3;//父类私有成员,子类公有继承,无法访问
}
};
void testCar() {
Cat c;
c.m_pub = 1;
//c.m_pro = 2;//不行,保护成员在类外部不可以访问,在类内部才可以访问,类内可以访问,类外不可以访问,要么是私有,要么是保护
}
class Dog : protected Animal {
public:
Dog() {
m_pub = 1;
m_pro = 2;
//m_pri = 3;//父类私有成员,子类保护继承,无法访问
}
};
//现在证明两个变量都是保护的
class PoliceDog :public Dog {
public:
PoliceDog() {
m_pub = 1;//证明不是私有 因为私有变量无论怎么继承 子类都拿不到 这个变量在父类Dog中一定不是私有成员,
m_pro = 2;//证明不是私有 因为私有变量无论怎么继承 子类都拿不到 这个变量在父类Dog中一定不是私有成员
//所以这两个变量在父类里面一定是保护成员
}
};
void testDog() {
Dog d;
//d.m_pub = 1; //类无法访问的话,要么是保护,要么是私有,我们还无法验证是保护还是私有
//d.m_pro = 2;//类无法访问的话,要么是保护,要么是私有,我们还无法验证是保护还是私有
}
class Pig : private Animal {
public:
Pig() {
m_pub = 1;
m_pro = 2;
//m_pri = 3;//父类私有成员,子类私有继承,无法访问
}
};
class WildPig :public Pig {
public:
WildPig() {
m_pub = 1;//证明该变量在父类 Pig中是私有的 因为如果是保护 子类公有继承一定能访问到
m_pro = 2;//证明该变量在父类 Pig中是私有的 因为如果是保护 子类公有继承一定能访问到
}
};
void testPig() {
Pig p;
//p.m_pub = 1;//类无法访问的话,要么是保护,要么是私有
//p.m_pro = 2;//类无法访问的话,要么是保护,要么是私有
}
int main() {
return 0;
}
//Ov Construction and Destruction Order
//构造和析构顺序
#include <iostream>
using namespace std;
/*
继承中,构造链里,先构造的后析构
d->c->b->a (d继承了c继承了b继承了a)
构造顺序:a b c d
析构顺序:d c b a
*/
class Animal {
public:
Animal() {
cout << “Animal 构造” << endl;
}
~Animal() {
cout << “Animal 析构” << endl;
}
};
class Cat : public Animal{
public:
Cat() {
cout << “Cat 构造” << endl;
}
~Cat() {
cout << “Cat 析构” << endl;
}
};
class BossCat : public Cat {
public:
BossCat() {
cout << “BossCat 构造” << endl;
}
~BossCat() {
cout << “BossCat 析构” << endl;
}
};
void Test() {
//Animal a;//调用函数时生成a对象 生成对象时调用构造函数 然后当函数销毁时 调用析构函数
//Cat c;//先调用父类的构造函数,再调自己构造函数,再调自己的析构函数,最后调用父类的析构函数,有点像一个个括号
BossCat b;//先调用父类的构造函数,再调自己构造函数,再调自己的析构函数,最后调用父类的析构函数,有点像栈 后进先出
}
int main() {
Test();//调用函数时生成a对象 生成对象时调用构造函数 然后当函数销毁时 调用析构函数
return 0;
}
//Object – Oriented 8 – 4 Access to Same – Named Attributes
//同名属性访问
#include <iostream>
using namespace std;
//同名属性:父类和子类都有一个名字相同的属性
// 子类不会覆盖父类,因为存储的位置不在一个内存地址上
//
class Animal {//父类
public:
Animal() {
m_Data = 17981;
}
int m_Data;
};
class Cat:public Animal {//子类
public:
Cat() {
m_Data = 29812;
}
int m_Data;
};
void Test() {
Cat c;
cout << c.m_Data << endl;
cout << c.Animal::m_Data << endl;//这个数据还在,用一个作用域来进行访问就好了
cout << &(c.m_Data) << endl;//不是同一个地址
cout << &(c.Animal::m_Data) << endl;//不是同一个地址
}
int main() {
Test(); //子类看起来会覆盖父类同名属性,其实并没有被覆盖掉
return 0;
}
//Object – Oriented 8 – 5 Access to Same – Named Function
//同名函数访问
#include <iostream>
using namespace std;
//父类和子类有一个名称相同的函数
class Animal{
public:
Animal() {
}
void eat() {
cout << “动物吃东西” << endl;
}
};
class Cat : public Animal {
public:
Cat() {
}
void eat() {
Animal::eat();//用作用域 这样就可以先调 动物吃东西
cout << “猫吃东西” << endl;
}
};
int main() {
Cat c;
c.eat(); //输出猫吃东西,
//c.Animal::eat();//就像同名变量一样 直接点出来就是能拿到自己的 这样就能拿到父类的函数了
return 0;
}
//Object – Oriented 8 – 6 Multiple Inheritance
//多继承
#include <iostream>
using namespace std;
//多继承:子类有一个,它可以继承多个父类
class BaseA {
public:
int m_A;
int m_Base;
BaseA() :m_A(0),m_Base(520){}//构造函数
};
class BaseB {
public:
int m_B;
int m_Base;
BaseB() :m_B(0), m_Base(1314) {}//构造函数
};
class BaseC {
public:
int m_C;
BaseC() :m_C(0) {}//构造函数
};
class Son : public BaseA, public BaseB, public BaseC {
};
int main() {
Son s;
s.m_A = 1;
s.m_B = 2;
s.m_C = 3;
//s.m_Base = 8;//这样写会导致不明确,因为父类A和B有一个同名变量
s.BaseA::m_Base = 8; //用定义域来拿到不同的m_Base值
s.BaseB::m_Base = 9;
cout << &s.BaseA::m_Base << endl;//不是同一个地址
//如果存储在同一个地址 那么编译器就会识别到
cout << &s.BaseB::m_Base << endl;//不是同一个地址
cout << sizeof(s) << endl; //总共继承了来自三个父类的5个整型 一个整型 4字节
return 0;
}