孤行者程序之路 2017-12-25 23:57 采纳率: 50%
浏览 2430
已采纳

C#中父类转换成子类之后为什么不具备子类的属性和方法了

笔者是新手,已经在学习面向对象了,可是有一个疑问一直想不通:根据里氏转换原则,父类对象如果里面存储的是一个子类对象,那么这个父类对象是能够强转成子类的。可是根据本人的理解,父类对象强转成子类之后应该就是一个子类对象吧,为什么不具备子类的属性和方法呢。
下面是具体案例:
比如我定义了一个父类对象Person:
Class Person
{
private string name; //定义person类的姓名字段和属性
public string Name
{
get{return name;}
set{name=value;}
}

private char sex; //定义Person类的性别字段和属性
public char Sex
{
get{return sex;}
set{sex=value;}
}

public void PersonSayHello()
{
Console.WriteLine("我是一个人类!");
}
}

然后我又定义了一个Person类的子类Student:
class Student:Person //继承于Person类
{
private int mathscore; //定义一个数学分数属性
public int MathScore
{
get{return mathscore;}
set{mathscore=value;}
}

public void StuSayHello()
{
Console.WriteLine("我是一个学生。");
}
}

然后我实际代码如下:
Person PER=new Student(); //创建一个Student对象,将其赋值给Person对象PER
Student STU=(Student)PER; //根据里氏转换原则,将PER对象转换成Student类型,并赋值给STU。

接下来就是问题了,我特意使用PER的GetType()方法试了转换之后PER确实是Student类型,但是我不能为PER的mathscore属性赋值,也不能调用PER作为一个Student对象的StuSayHello()方法,这是为什么呢。

展开全部

  • 写回答

6条回答 默认 最新

  • 华山派副掌门人 2017-12-26 00:31
    关注

    你好,Person PER=new Student();
    Student STU=(Student)PER;
    首先这是多态,这两段代码是没有问题的,但是PER.mathscore=5;Per.StuSayHello()是不合法的,因为mathscore和StuSayHello()是子类的扩展属性和方法,在父类里面没有,子类没有重写父类里面任何方法,Person PER=new Student();这段代码虽然是父类引用指向子类对象,但是只有子类重写了父类的方法后,Per.StuSayHello()这样调用才会执行子类重写后的StuSayHello()方法。总结一下:多态的弊端,不能使用子类提油的功能,因为子类特有方法不是重写的,如果在多态情况下想使用子类特有的方法,应该向下转型。至于为什么PER.mathscore=5;是错误的,是因为父类中没有这个属性,你使用父类引用去访问这个成员会显示找不到符号等错误。再总结一下:多态的前提:A:有继承 B:有实现 C:有方法重写 D:有父类引用指向子类对象。多态中成员访问特点:A:访问成员变量:编译看左边,运行看左边。
    B:访问成员方法:编译看左边:运行看右边。(如果子类有方法重写,就使用子类重写过的方法;父类引用不能使用子类特有的方法)

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(5条)
编辑
预览

报告相同问题?

悬赏问题

  • ¥15 DevEco studio开发工具 真机联调找不到手机设备
  • ¥15 请教前后端分离的问题
  • ¥100 冷钱包突然失效,急寻解决方案
  • ¥15 下载honeyd时报错 configure: error: you need to instal a more recent version of libdnet
  • ¥15 距离软磁铁一定距离的磁感应强度大小怎么求
  • ¥15 霍尔传感器hmc5883l的xyz轴输出和该点的磁感应强度大小的关系是什么
  • ¥15 vscode开发micropython,import模块出现异常
  • ¥20 Excel数据自动录入表单并提交
  • ¥30 silcavo仿真,30分钟,只需要代码
  • ¥15 FastReport 怎么实现打印后马上关闭打印预览窗口