• C#:(补)this和base的区别


    这一篇是补给C#:类的继承的。

    由于在写这篇的时候,发现base和this在访问同一成员的时候编译期提示颜色变成灰色,所以才决定将base和this的区别查一下

    微软官方给出的base的介绍其实就是base和this的区别base关键字

    调用基类上被其它方法重写的方法--准确来说是在子类中使用base可以调用基类中那个"原生"方法

    namespace ExtendsDemo
    {
        class Program
        {
            static void Main(string[] args)
            {
                Shape square = new Square();
                Console.ReadLine();
            }
        }
    
        class Shape
        {
            public double Area { get; set; }
            public string Color { get; set; }
            //使用virtual表明 该函数成员的功能希望在子类中被更新
            public virtual void ShowInfo()
            {
                Console.WriteLine($"面积:{Area},颜色:{Color}");
            }
        }
    
        class Square : Shape
        {
            public Square()
            {
                base.ShowInfo();
                this.ShowInfo();
            }
            public override void ShowInfo()
            {
                Console.WriteLine("我是长方形,对边相等且平行...");
            }
        }
    }
    /*输出:
    面积:0,颜色:
    我是长方形,对边相等且平行...
    */
    

    base的第一点作用,重在描述base的能力:如果子类重写了父类函数成员,那么在子类中如果不用base,试问还有谁还能访问到基类中那个“原生”方法?(this么?试一下就知道不行--这就是this和base的第一点区别)虽然明白了base有这种作用,但是我却并不知道这个作用在实际编码中有什么用.....

    指定创建派生类实例时应调用的基类构造函数

    • 在创建子类实例的时候,由于C#要求必须要先调用基类构造函数,如果基类没有提供构造函数还好(编译器会帮我们隐式调用基类默认构造函数)
    • 但如果基类型没有提供默认构造函数,只是提供了一些带参构造函数,那么编译器可不知道我们要调用哪一个(从下图的报错信息可知:这种情况下编译器不帮我们隐式调用默认构造函数了)
    • 这时base作为拥有"可以在子类中调用基类构造函数"的能力,华丽出场
    namespace ExtendsDemo
    {
        class Program
        {
            static void Main(string[] args)
            {
                Shape square = new Square();
                square.ShowInfo();
                Console.ReadLine();
            }
        }
    
        class Shape
        {
            public double Area { get; set; }
            public string Color { get; set; }
            public Shape(double area)
            {
                this.Area = area;
            }
            public Shape(double area,string color)
            {
                this.Area = area;
                this.Color = color;
            }
            //使用virtual表明 该函数成员的功能希望在子类中被更新
            public virtual void ShowInfo()
            {
                Console.WriteLine($"面积:{Area},颜色:{Color}");
            }
        }
    
        class Square : Shape
        {
            public Square():base(12.3)//访问基类单参数的构造函数
            {
    
            }
    
            public Square(double area,string color):base(area,color)//访问基类两个参数的构造函数
            {
    
            }
            public override void ShowInfo()
            {
                base.ShowInfo();
                Console.WriteLine("我是长方形,对边相等且平行...");
            }
        }
    }
    /*输出:
    面积:12.3,颜色:
    我是长方形,对边相等且平行...
    */
    

    上面展示了base的第二种能力,这勉强算是base和this的第二个区别吧?

    成员如果被new修饰,base和this都访问这个成员,此时base、this也是有区别的

    namespace ExtendsDemo
    {
        class Program
        {
            static void Main(string[] args)
            {
                Shape square = new Square();
                Console.ReadLine();
            }
        }
    
        class Shape
        {
            public double Area { get; set; }
            public string Color { get; set; }
            public Shape(double area)
            {
                this.Area = area;
            }
    
            //使用virtual表明 该函数成员的功能希望在子类中被更新
            public virtual void ShowInfo()
            {
                Console.WriteLine($"面积:{Area},颜色:{Color}");
            }
        }
    
        class Square : Shape
        {
            public Square() : base(12.3)
            {
                base.ShowInfo();//base已经不是灰色了,表示base和this访问的成员不一样了。
                this.ShowInfo();
            }
            //ShowInfo成员被new修饰,导致这个Square的ShowInfo和Shape的ShowInfo不一致
            public new virtual void ShowInfo()
            {
                Console.WriteLine("我是长方形,对边相等且平行...");
            }
        }
    }
    /*输出:
    面积:12.3,颜色:
    我是长方形,对边相等且平行...
    */
    

    如果你看了我写的C#:多态,就知道为什么new会产生如此现象--总之不建议在继承链中使用new,修饰函数成员

    非以上描述情况,使用base和this访问同一成员,没有区别:这时base和this可以不写。

    namespace ExtendsDemo
    {
        class Program
        {
            static void Main(string[] args)
            {
                Shape square = new Square();
                Console.ReadLine();
            }
        }
    
        class Shape
        {
            public int cost;
            public double Area { get; set; }
            public string Color { get; set; }
            public Shape(double area)
            {
                this.Area = area;
            }
            public virtual void ShowInfo()
            {
                Console.WriteLine($"面积:{Area},颜色:{Color}");
            }
        }
    
        class Square : Shape
        {
            public Square() : base(12.3)
            {
                Console.WriteLine(base.cost+"---"+this.cost);//base和this访问数据成员时没有却区别
                Console.WriteLine(base.Area+"---"+this.Area);//base和this访问普通的函数成员时也没有区别
            }
            public override void ShowInfo()
            {
                Console.WriteLine("我是长方形,对边相等且平行...");
            }
        }
    }
    /*输出:
    0---0
    12.3---12.3
    */
    

    以上便是对base和this的区别的总结,记录下来以便以后查阅。

  • 相关阅读:
    msfvenom生成不同类型shell
    (CVE-2021-21972) VM vCenter任意文件上传漏洞复现
    linux新建普通账户并添加密码
    Linux监控平台、安装zabbix、修改zabbix的admin密码
    LVS DR模式搭建、keepalived+lvs
    负载均衡集群相关、LVS介绍、LVS调度算法、LVS NAT模式搭建
    集群相关、用keepalived配置高可用集群
    MySQL主从、环境搭建、主从配制
    Tomcat配置虚拟主机、tomcat的日志
    Tomcat介绍、安装jdk、安装Tomcat、配置Tomcat监听80端口
  • 原文地址:https://www.cnblogs.com/bigbosscyb/p/13876212.html
Copyright © 2020-2023  润新知