美文网首页C#
ReC# : 多态插曲

ReC# : 多态插曲

作者: 伪犬儒李长歌 | 来源:发表于2017-08-18 18:02 被阅读0次

    从零系列的插曲,前天被问到了一个这样的问题:如何用父类实例去调用子类方法。恕我当时学业不精对多态认识还是不到位,今天就此问题稍作研究。

     class Animal {
            public string Name;
            public Animal() {
                this.Name = "Animal";
            }
    
            public void Called() {
                Console.WriteLine("Animal");
            }
        }
    
     class Cat : Animal {
            public Cat() {
                this.Name = "Cat";
            }
            public void Called() {
                Console.WriteLine("Cat");
            }
            public void Called(string str) {
                Console.WriteLine(str);
            }
            public void Called1() {
                Console.WriteLine("NoCat");
            }
        }
    

    为了实际验证一下如何才能达到父类调用子类的方法,我创建了一个Animal类包含一个简单的方法用来检测。然后派生了一个子类Cat,并重载了父类的方法Called(str),和添加了一个新方法Called1。

       Animal animal = new Animal();
               Cat cat = new Cat();
    
     animal.Called();
                cat.Called();
                cat.Called("YesCat");
                cat.Called1();
    

    首先是简单测试一下,输出结果正常:分别是Animal 、Cat、YesCat、NoCat
    接着就是测试父类如何调用子类了。

          Animal animal1 = new Cat();
    

    声明一个Animal类型的变量animal1,用子类去创建它的实例。上面这句话的意思就是Animal类型的引用去指向一个Cat类实例,因为new 在内存上的是一个Cat类。按这个道理来想那么直接就可以调用子类方法呀,于是...

                animal1.Called();
                animal1.Called("YesCat");
                animal1.Called1();
    

    高高兴兴写了这三行然后按下了启动,(⊙v⊙)......
    并不能启动...( ⊙ o ⊙ )
    很显而易见animal1中无法调用Called(str)和Called1这两个方法。
    原因是:在编译的时候Animal类型中不包含对Called(str)方法和Called1()方法的定义,编译将会报错。于是乎注释了下面条:

                animal1.Called();
                //animal1.Called("YesCat");
                //animal1.Called1();
    

    可喜可贺,返回的结果是Animal
    这说明了Animal类型的引用虽然指向了Cat类,但是只能访问Cat类中所继承的Animal类方法。
    那要如何才能调用子类的方法呢?
    这就需要使用强转或者as

     (animal1 as Cat).Called();
                (animal1 as Cat).Called("YesCat");
                (animal1 as Cat).Called1();
    

    返回的结果是:Cat、YesCat、NoCat
    恩,这就实现了父类调用子类方法的目的。

    as 与 强转的区别

    as 只支持引用类型的转换,且不会抛出异常。
    强转则支持值类型和引用类型,在转换不匹配时会抛出异常。

    相关文章

      网友评论

        本文标题:ReC# : 多态插曲

        本文链接:https://www.haomeiwen.com/subject/sejarxtx.html