简述为什么不能用父类给子类赋值

来源:互联网 发布:ubuntu 迅雷 编辑:程序博客网 时间:2024/05/04 08:51

在学习类的知识时,学习到子类可以给父类赋值,而父类却不可以给子类赋值。当时就听的云里雾里,如今学到Java,对此更是困惑。稍稍思索了一下午,小有收获,决定同大家分享一下。此处以C++做演示。

先给出一个正常的Tree类作为父类:

class Tree{int hight;int weight;int age;void OutInfo(){cout << "Hight:" << this->hight << endl;cout << "Weight:" << this->weight << endl;cout << "Age:" << this->age << endl;}};/*定义一个名为Tree的类代表树这一大类类中有高度、重量、树龄等信息,并有方法OutInfo用于输出树龄等*/

下边是一个借由Tree派生出的子类Pine:


class Pine : public Tree{int NumOfPineCones;void OutNum(){cout << "Num of PineCones is " << this->NumOfPineCones << endl;}};/*以Tree为父类派生出子类Pine(松树),并且有子类特有的NumOfPineCones(松果数)并且新定义了一个方法OutNum用于输出松果数*/

现在如果在main函数里边这样写:


int main(){Tree * t1 = new Pine();t1->OutInfo();}


很明显,编译是可以通过的,因为子类允许给父类赋值;我们也可以看到t1实际上是Tree类型:




而如果反过来:


int main(){Pine * t1 = new Tree();t1->OutInfo();}

编译会直接出错。看一下VS给出的错误提示信息:



很明显,VS给出的解释是不能用Tree给Pine赋值。为什么?


依我拙见,如果可以Pine * p1 = new Tree();则会造成这样一种后果:p1指向的实际上应该是Pine类,因为指针类型是Pine * ;而new Tree语句申请出来的空间是Tree类型的,所以编译器会进行转化,把Tree类转化成Pine类,但是Pine类之中有一个方法OutNum(),一则编译器不知道OutNum()的详细代码,二则如果编译器强制跳过OutNum()方法,把Tree类转化为Pine类的话,就意味着这个对象可以当做Pine的对象使用,那如果我调用p1->OutNum()就会出错,因为对象中根本没有OutNum()这个方法,没有这个方法那他就不能称之为Pine类,依旧只是Tree类,也就是说编译器的转化失败了,而这也刚好对应VS的错误提示信息: 无法从“Tree *”转换为“Pine *” 。 因此而言,无法用父类给子类赋值(或者做初始化)。

阅读全文
1 0
原创粉丝点击