C# 子类只覆盖父类的属性,调用方法时为什么获取不到覆盖的值?

发布于 2022-09-07 21:39:08 字数 4504 浏览 66 评论 0

代码如下,主要看最后的

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CSharpClassTest
{
    /*
     * 原始:https://blog.csdn.net/tc_1337/article/details/80957140#commentsedit
     */

    class A
    {
        public static string StaticStr = "A 的静态字段";
        public string NonStaticStr = "A 的非静态字段";

        public string NoStaticProperty { get; set; } = "A 的非静态属性";

        public static void StaticMethod()
        {
            Console.WriteLine("A 的静态方法");
        }

        public void NonStaticMethod()
        {
            Console.WriteLine($"A 的非静态方法输出:A 的非静态字段 | A 的非静态属性输出:{NonStaticStr} | {NoStaticProperty}");
        }

    }

    class B : A
    {

        public static string StaticStr = "B 的静态字段";
        public string NonStaticStr = "B 的非静态字段";

        public static void StaticMethod()
        {
            Console.WriteLine("B 的静态方法");
        }

        public void NonStaticMethod()
        {
            Console.WriteLine($"B 的非静态方法输出:{NonStaticStr}");
        }

    }

    class C : A
    {

    }

    class D : A
    {
        public string NonStaticStr = "D 的非静态字段";
    }

    class E : A
    {
        public string NoStaticProperty { get; set; } = "E 的非静态属性";
    }

    class Program
    {
        static void Main(string[] args)
        {
            C c = new C();
            Console.WriteLine("使用 单纯继承A的C类对象 进行调用:");
            Console.WriteLine(c.NonStaticStr);      // A 的非静态字段
            c.NonStaticMethod();                    // A 的非静态方法输出:A 的非静态字段 | A 的非静态属性
            Console.WriteLine("-------------------------------\r\n");

            A c1 = new C();
            Console.WriteLine("使用 以C类实例化的A类对象 进行调用:");
            Console.WriteLine(c1.NonStaticStr);     // A 的非静态字段
            c1.NonStaticMethod();                   // A 的非静态方法输出:A 的非静态字段 | A 的非静态属性
            Console.WriteLine("-------------------------------\r\n");

            B b = new B();
            Console.WriteLine("使用 覆盖了A类成员的B类对象 进行调用:");
            Console.WriteLine(b.NonStaticStr);      // B 的非静态字段
            b.NonStaticMethod();                    // B 的非静态方法输出:B 的非静态字段
            Console.WriteLine("-------------------------------\r\n");

            A b1 = new B();
            Console.WriteLine("使用 以B类实例化的A类对象 进行调用:");
            Console.WriteLine(b1.NonStaticStr);     // A 的非静态字段
            b1.NonStaticMethod();                   // A 的非静态方法输出:A 的非静态字段 | A 的非静态属性
            Console.WriteLine("-------------------------------\r\n");

            D d = new D();
            Console.WriteLine("使用 仅覆盖了A类非静态字段的D类对象 进行调用:");
            Console.WriteLine(d.NonStaticStr);     // D 的非静态字段
            d.NonStaticMethod();                   // A 的非静态方法输出:A 的非静态字段 | A 的非静态属性
            Console.WriteLine("-------------------------------\r\n");

            E e = new E();
            Console.WriteLine("使用 仅覆盖了A类非静态属性的E类对象 进行调用:");
            Console.WriteLine(e.NoStaticProperty); // E 的非静态属性
            e.NonStaticMethod();                   // A 的非静态方法输出:A 的非静态字段 | A 的非静态属性
            Console.WriteLine("-------------------------------\r\n");
        }
    }
}

@Woody 的启发:

    class AA
    {
        public virtual string NoStaticProperty { get; set; } = "AA 的非静态虚属性";

        public void NonStaticMethod()
        {
            Console.WriteLine($"AA 的非静态方法输出: 非静态属性:{NoStaticProperty}");
        }

    }

    class BB : AA
    {
        public override string NoStaticProperty { get; set; } = "BB 的非静态属性";
    }

    class CC : AA
    {
        public new string NoStaticProperty { get; set; } = "CC 的非静态属性";
    }
    
    //...
    
BB bb = new BB();
Console.WriteLine("使用 仅覆盖了AA类非静态虚属性的BB类对象 进行调用:");
Console.WriteLine(bb.NoStaticProperty); // BB 的非静态属性
bb.NonStaticMethod();                   // AA 的非静态方法输出: 非静态属性:BB 的非静态属性
Console.WriteLine("-------------------------------\r\n");

CC cc = new CC();
Console.WriteLine("使用 new了AA类非静态虚属性的CC类对象 进行调用:");
Console.WriteLine(cc.NoStaticProperty); // CC 的非静态属性
cc.NonStaticMethod();                   // AA 的非静态方法输出: 非静态属性:AA 的非静态虚属性
Console.WriteLine("-------------------------------\r\n");

AA ab = new BB();
Console.WriteLine("使用 以BB类实例化的AA类对象 进行调用:");
Console.WriteLine(ab.NoStaticProperty); // BB 的非静态属性
ab.NonStaticMethod();                   // AA 的非静态方法输出: 非静态属性:BB 的非静态属性
Console.WriteLine("-------------------------------\r\n");

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

扎心 2022-09-14 21:39:08

楼主写的例子很好呈现了关于这4个类的几种用法会得到什么样的值。

楼主首先得搞清楚重写的概念,然后再来看这几个例子。
其实你定义的这些方法属性和继承没有关系。

首先,这个下面例子,你定义了一个B,那么获取的任何值都会是B的值。

B b = new B();

其次,下面这个例子,你定义了一个A,那么获取的任何值都会是A的值,不管它的实例是不是B。因为你在B里面没有重写任何A的东西。

A b1 = new B();

你想要BCDE能覆盖父类A的值,那么你需要override他们。应该像下面这些写:


public class A 
{
    public virtual void NonStaticMethod() 
    {
        Console.WriteLine("A");
    }
}

public class B : A 
{
    public override void NonStaticMethod()
    {
        Console.WriteLine("B");
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文