C#向上转型与向下转型(转)


原文地址:https://blog.csdn.net/wangqingbo0829/article/details/48474173

 

向上转型:将子类对象转为父类对象。此处父类对象可以是接口。
向下转型:把父类对象转为子类对象。
讨论两种继承:继承自抽象类、继承自非抽象类(这两种继承所对应的转型稍有不同)

继承自非抽象类

父类:动物类Animal(有一个叫声方法“call()”)
    class Animal { public void call() { Console.WriteLine("无声的叫唤"); } }
 子类:狗类Dog(继承于“动物类”,覆盖父类“call()”方法,扩展嗅觉灵敏“ smell()”方法)
    class Dog : Animal { // new的作用是隐藏父类的同名方法
        public new void call() { Console.WriteLine("叫声:汪~汪~汪~"); } public void smell() { Console.WriteLine("嗅觉相当不错!"); } }

向上转型:将子类对象转为父类对象。此处父类对象可以是接口。

转化后的父类对象具有父类所有方法,若方法被子类重写override,那么实际调用时,调用的是重写后的实现。同时支持子类到父类的强转。特注:但不能调用子类扩展方法(父类不具有的方法)。
            Animal animal = new Dog();             //向上转型①
 animal.call(); //打印出“无声的叫唤”,调用的是父类本身的call方法。 // animal.smell(); //出错,不存在此方法。
目前看来,感觉animal跟Dog一点关系也没有。但请继续往下看

向下转型:把父类对象转为子类对象。

    经②转化后的子类对象,跟一般的继承子类对象一样。具有子类所有方法(包括重写方法)+父类所有方法(被重写的方法,按重写的算。)

    例:

Dog dog = (Dog)animal;                      //向下转型②
dog.call();                 //打印出“叫声:汪~汪~汪~”,即调用的是Dog类的call方法。
dog.smell();                //打印出“嗅觉相当不错!”,即子类方法可用。

特注:若Animal animal = new Dog()改成Animal animal = new Animal(),那么Dog dog = (Dog)animal ③ 将不被支持,而出错。这是相当于用父类来替换子类,因为子类具有扩展,父类不能做到完全替代。

// Dog dog2 = new Animal(); //编译都无法通过,报错“存在一个显示转换” // Dog dog3 =(Dog)new Animal(); //运行报错,报错“无法将Animal类型转化为Dog类型”<span style="font-size:18px;">s④</span>
③与④类同。
    Animal animal = new Dog()好似给animal声明了一个大的空间(放置Dog的空间),用的时候,允许有空隙;同等大小的内容(Dog对象)刚好容纳,很贴身;小一些的内容(Animal对象)放到里面,虽有空隙,但是没问题的


继承自抽象类

父类:动物类Animal_a(有一个叫声方法“call()”) 
    abstract class Animal_a { public abstract void call(); }
子类:狗类Dog_a(继承于“动物类”,实现父类“call()”方法,扩展嗅觉灵敏“ smell()”方法)


    class Dog_a : Animal_a { public override void call() { Console.WriteLine("叫声:汪~汪~汪~"); } public void smell() { Console.WriteLine( "嗅觉相当不错!"); } }
这里是一般的继承知识:
Animal_a animal_a = new Dog_a();               //向上转型
animal_a.call();      //打印出“叫声:汪~汪~汪~” // animal_a.smell(); //不存在此方法
子类实现抽象类,调用方法时,自动找到子类同名方法,执行子类同名方法。向上转型时,转型后的对象只具有父类方法和子类对父类重新(实现)的方法。

总结:

向上转型是自由的;向下转型是有约束条件的。
非抽象继承,子类对象、父类对象的方法都能调到(用子类对象能调到子类对象的方法,用父类对象能调用父类对象的方法)。










免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM