目录
代码分析:
代码中我们使用了三种方式:
为什么子类对象可以赋值给父类对象?
子类型的传递性:
使用父类的指针指向子类的对象:
总结:
子类型和多态的联系及什么是多态
那父类指针指向子类对象的用处在哪?
子类型: 从名字看就知道和继承有关。
子类型其实就是子类对象可以代替父类对象,赋值给父类的变量。
当使用public继承(必须)的子类对象,可以冒充是父类对象
就是在函数参数需要传入父类时可以传入一个子类
class Father {
public:
Father(const string& name, int age);
private:
string name;
int age;
};
class Son : public Father {
public:
Son(const string& name, int age, const string& love);
private:
string love;
};
int main(void) {
Father f("张三",50);
Son s("张三儿子", 15, "小美");
// 第一种
f = s;
Father f0 = s;
// 第二种
Father* f1 = &s;
// 第三种
Father& f2 = s;
system("pause");
return 0;
}
Father::Father(const string& name, int age)
{
this->name = name;
this->age = age;
}
Son::Son(const string& name, int age, const string& love):Father(name,age)
{
this->love = love;
}
代码分析:
代码中我们使用了三种方式:
1. 使用父类的指针指针指向子类对象。 (常用)
2. 使用将子类赋值给父类的引用。
3. 直接将子类对象赋值给父类对象。
这种情况
为什么子类对象可以赋值给父类对象?
因为:子类继承自父类,父类中的属性即方法子类其实都有,而且子类还可以再父类的基础上增加新的方法和属性,所以子类中的方法和属性>=父类中,用子类给父类赋值的时候,只需要将子类中多余父类的部分丢弃,赋值它们共有的部分。
子类型的传递性:
如果B是A的子类型,C是B的子类型,那么C也是A的子类型。 (但是反过来是错误的)
使用父类的指针指向子类的对象:
使用父类的指针指向子类的对象。然后我们使用父类的指针局可以访问子类的属性和函数。
至于访问函数的过程我们会在虚函数中说到。现在主要来说一下访问子类的属性。
上面我们使用父类指针指向子类对象,然后使用指针访问name和子类新增的属性love。
会发现在访问name是输出的是儿子的名字, 访问love的时候编译器报错了 -- 报错信息: Father类中不存在love成员。
如何理解上面这种情况呢?
可以这样理解, 我们在继承的时候,从父类继承来的属性在内存中是存放在最上面的,所以我们可以理解为,在我们使用父类指针指向子类对象的时候,编译器会使用子类从父类中继承来的属性,使用这些属性的值,初始化一个父类对象,然后让父类指针指向。(仅供理解)
使用父类指针访问,并且打印数据,和子类中的数值是相同的。而子类中新增的属性,父类中是没有的,所以你使用父类的指针去访问love会出错。
总结:
上面一大堆其实就是,父类指针指向子类对象,使用此指针只能访问子类从父类继承或者重写的属性和方法。 子类新增的是无法访问的。
子类型和多态的联系及什么是多态
多态: 顾名思义就是多种形态。其实多态的实现就是使用父类指向子类,然后使用父类指针来调用子类的方法。
举个例子: 我们养了一只猫和一只狗,它们都有吃的功能,但是吃的东西不一样,我们在喂食物的时候,如果是猫我们就喂猫粮,如果是狗我们就需要喂狗粮。同样是吃,但是对于不同的对象,就有不同的实现方式(不同形态),这其实就是多态。
那父类指针指向子类对象的用处在哪?
猫和狗共有吃的方法,并且都属于动物类,所以我们可以将吃的方法写在动物类中写上吃的方法,让猫和狗继承这个方法,但是猫和狗吃的又不一样,所以猫和狗重写吃的方法,满足自己的需求。
我们人喂食其实也是一个功能,也可以分装成一个函数,函数的参数用于传入要喂食的对象,如果我们不使用多态,我们一个吃函数就要写好几个重载,因为你喂猫和喂狗参数是不一样的。但是如果我们使用多态, 也就是父类指针指向子类对象,那么我们使用父类指针就可以直接去访问子类从父类中继承来的方法。
我们让父类(此处就是动物类)的指针或者引用,作为喂食函数的参数,我们无论传入猫对象还是狗对象,我们直接使用父类对象调用吃的方法,会根据指针指向的对象调用其对应的方法,这样我们只使用了一个函数就实现了喂食的功能。 而且以后再养其它的小动物,也不需要新增任何的喂食方法,因为都是动物类的子类,直接使用前面写的喂食方法即可。