简述为什么不能用父类给子类赋值
2017-08-30 23:26
197 查看
在学习类的知识时,学习到子类可以给父类赋值,而父类却不可以给子类赋值。当时就听的云里雾里,如今学到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 *” 。 因此而言,无法用父类给子类赋值(或者做初始化)。
先给出一个正常的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 *” 。 因此而言,无法用父类给子类赋值(或者做初始化)。
相关文章推荐
- 关于原型链和继承问题的思考:为什么不能直接把父类的prototype赋值给子类的prototype
- 父类不能赋值给子类的猜想。
- 子类为什么不能重写父类的静态方法
- 为什么父类引用可以指向子类对象 子类引用不能指向父类对象 泛型
- 子类为什么不能重写父类的静态方法
- 为什么不能在子类的初始化列表里初始化父类的成员
- 子类为什么不能重写父类的静态方法
- 从JVM角度看为什么子类不能重写父类静态方法
- 子类为什么不能重写父类的静态方法
- 为什么java中子类重写父类的方法时声明抛出异常不能比父类范围大
- 子类用一个名为subitems的数组属性保存父类对象,为什么不能获取父类对象的信息呢???在main函数中subitems为空,不知道为什么。
- 为什么子类中不能访问另一个包中父类中的protected方法?
- 为什么子类中不能访问另一个包中父类中的protected方法?
- 为什么子类的构造方法在运行之前,必须调用父类的构造方法?能不能反过来?为什么不能反过来?
- JAVA为什么子类继承父类方法之后,不能抛出比父类更多的异常?
- 异常父类为什么java中子类重写父类的方法时声明抛出异常不能比父类范围大
- JAVA为什么子类继承父类方法之后,不能抛出比父类更多的异常?
- 为什么不能在子类的初始化列表里初始化父类的成员
- 子类为什么不能重写父类的静态方法
- 子类重写父类的方法时声明抛出异常不能比父类范围大