• c#中override重写和new隐藏


    最近学习c#,昨晚看书看到多态。由于个人本身是从事java开发,于是拿来做对比便是自然的。

    进入主题吧。

    c#中,子类要重写基类的方法,必须要基类声明中带有virtual关键字方法或者带有abstract关键字的抽象方法,然后子类中重写该方法时使用override关键字。

    例如:

     class A
        {
            private String name;
            public String Name
            {
                get
                {
                    return name;
                }
                set
                {
                    name = value;
                }
            }
    
            public A(String name)
            {
                this.name = name;
            }
    
            public virtual String Test()
            {
                return name;
            }
        }
    
        class B : A
        {
            private int age;
            public B(String name,int age)
                : base(name)
            {
                this.age = age;
            }
            public override string Test()
            {
                return this.Name + ":" + age;
            }
        }

    对于带有关键字abstract的抽象方法,子类中必须要重写,这与java中都是一样的。
    但是在java中,子类重写基类的普通方法,只需要与父类的方法声明一致,就会重写父类的方法。

    重写之后,在多态上的表现便会和大家期望的一致,调用子类重写的方法,而不再是调用父类的方法了。

     static void Main()
            {
                A c1 = new A("Tom");
                System.Console.WriteLine( c1.Test());
                A c2 = new B("Jerry",20);
                System.Console.WriteLine(c2.Test()); 
            }

    会发现后台输出的是

    到这里,除了写法上比java多了两个关键字,其他都是一样的,很好理解。但是在使用new隐藏父类方法的时候,就稍微有点晕了。

     class C : A
        {
            public String Code { set; get; }
            public C(String name)
                : base(name)
            {
                this.Code = "100001";
            }
    
            public new String Test()
            {
                return this.Name + ":" + this.Code;
            }
           
        }

    如上,使用new关键字隐藏父类的Test方法,这里,隐藏父类方法,不像重写那么严格,关键字可以与父类不同,甚至连返回类型也可以不同,但是方法名和参数必须一致。

    运行代码

     static void Main()
            {
                System.Console.WriteLine("这是main方法");
                A c1 = new A("Tom");
                System.Console.WriteLine( c1.Test());
                B c2 = new B("Jerry",20);
                System.Console.WriteLine(c2.Test());
                C c3 = new C("Anlex");
                System.Console.WriteLine(c3.Test());
            }

    会发现结果,与之前重写父类方法得到的效果一致,于是不太明白new到底做了什么用。

    但是细心的朋友们一定注意到了,这里给大家埋了一个坑,运行的代码里,都是定义了自己的对象,运行自己的方法,结果自然会是如此了,根本就没有体现出多态。

    如果这里是定义父类的变量,去指向子类的实体的话。

    static void Main()
            {
                System.Console.WriteLine("这是main方法");
                A c1 = new A("Tom");
                System.Console.WriteLine( c1.Test());
                A c2 = new B("Jerry",20);
                System.Console.WriteLine(c2.Test());
                A c3 = new C("Anlex");
                System.Console.WriteLine(c3.Test());
                System.Console.ReadLine();
                
            }

    结果便是:

    这时,c2.Test()是调用了子类重写的方法,而c3.Test()是调用了父类的方法,并不会调用类C里的Test()方法。

    到这里,我想大家都理解隐藏的意思了吧。也明白书上一直强调的,要慎用new关键字隐藏父类方法了吧。

  • 相关阅读:
    flowable流程中心设计之http监听器(十)
    flowable流程中心设计之自定义sql(十)
    flowable流程中心设计之相关表(十六)
    Spring Boot源码阅读自动化Starter原理(四)
    flowable流程中心设计之是否是发起人节点(十四)
    flowable流程中心设计之自动完成任务(十三)
    Spring源码系列导航
    设计思路判断是否有修改数据
    flowable流程中心设计之流程进度图扩展(十五)
    树莓派4B安装 百度飞桨paddlelite 做视频检测 (一、环境安装)
  • 原文地址:https://www.cnblogs.com/huhy/p/3520933.html
Copyright © 2020-2023  润新知