继承和实现的明显区别

  事情的起因是这样的。。。

  有人在群里出了一道题:

  

    struct Point
    {
        private int _x;
        private int _y;

        public Point(int x, int y)
        {
            _x = x;
            _y = y;
        }

        public void Change(int x, int y)
        {
            _x = x;
            _y = y;
        }

        public override string ToString()
        {
            return string.Format("x : {0}, y : {1}", _x, _y);
        }
    }




            var point = new Point(1, 2);
            var obj = (object)point;
            ((Point)obj).Change(2, 3);
            MessageBox.Show(obj.ToString());

  问输出结果是多少,当然是 : x : 1, y : 2,这里没有问题,因为并没有读取设置后的值。

    struct Point : IChange
    {
        private int _x;
        private int _y;

        public Point(int x, int y)
        {
            _x = x;
            _y = y;
        }

        public Point Change(int x, int y)
        {
            _x = x;
            _y = y;
            return this;
        }

        public override string ToString()
        {
            return string.Format("x : {0}, y : {1}", _x, _y);
        }
    }

            var point = new Point(1, 2);
            var obj = (object)point;
            ((Point)obj).Change(2, 3);
            MessageBox.Show(((Point)obj).Change(2, 3).ToString());

  这样肯定就是2,3了。

  然后,有人干了这样一件事:

    interface IChange
    {
        Point Change(int x, int y);
    }

    struct Point : IChange
    {
        private int _x;
        private int _y;

        public Point(int x, int y)
        {
            _x = x;
            _y = y;
        }

        public Point Change(int x, int y)
        {
            _x = x;
            _y = y;
            return this;
        }

        public override string ToString()
        {
            return string.Format("x : {0}, y : {1}", _x, _y);
        }
    }

            var point = new Point(1, 2);
            var obj = (object)point;
            ((IChange)obj).Change(2, 3);
            MessageBox.Show(obj.ToString());

  实在是,我看到了结果是2,3才想起来,interface是引用类型的,而实现接口并不是继承,话说结构体也不能继承,而这里很明显区分出来的,实现只是实现了接口的方法,而具体是引用还是值类型并没有关系,除了实现了定义的指定方法外,就没有任何关系了,从这个场景也可以看出来,里氏替换并不适合实现接口的不同的类,虽然编译可能是正确的,但结果可能是迥异的。

  至于确定interface是引用类型,可以通过VS自带命令行工具打开ildasm查看编译好的IL代码查看。

原文地址:https://www.cnblogs.com/saaav/p/4538934.html