鍍金池/ 問答/Java  C  C#  網(wǎng)絡(luò)安全/ C# 子類只覆蓋父類的屬性,調(diào)用方法時(shí)為什么獲取不到覆蓋的值?

C# 子類只覆蓋父類的屬性,調(diào)用方法時(shí)為什么獲取不到覆蓋的值?

代碼如下,主要看最后的

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 的靜態(tài)字段";
        public string NonStaticStr = "A 的非靜態(tài)字段";

        public string NoStaticProperty { get; set; } = "A 的非靜態(tài)屬性";

        public static void StaticMethod()
        {
            Console.WriteLine("A 的靜態(tài)方法");
        }

        public void NonStaticMethod()
        {
            Console.WriteLine($"A 的非靜態(tài)方法輸出:A 的非靜態(tài)字段 | A 的非靜態(tài)屬性輸出:{NonStaticStr} | {NoStaticProperty}");
        }

    }

    class B : A
    {

        public static string StaticStr = "B 的靜態(tài)字段";
        public string NonStaticStr = "B 的非靜態(tài)字段";

        public static void StaticMethod()
        {
            Console.WriteLine("B 的靜態(tài)方法");
        }

        public void NonStaticMethod()
        {
            Console.WriteLine($"B 的非靜態(tài)方法輸出:{NonStaticStr}");
        }

    }

    class C : A
    {

    }

    class D : A
    {
        public string NonStaticStr = "D 的非靜態(tài)字段";
    }

    class E : A
    {
        public string NoStaticProperty { get; set; } = "E 的非靜態(tài)屬性";
    }

    class Program
    {
        static void Main(string[] args)
        {
            C c = new C();
            Console.WriteLine("使用 單純繼承A的C類對(duì)象 進(jìn)行調(diào)用:");
            Console.WriteLine(c.NonStaticStr);      // A 的非靜態(tài)字段
            c.NonStaticMethod();                    // A 的非靜態(tài)方法輸出:A 的非靜態(tài)字段 | A 的非靜態(tài)屬性
            Console.WriteLine("-------------------------------\r\n");

            A c1 = new C();
            Console.WriteLine("使用 以C類實(shí)例化的A類對(duì)象 進(jìn)行調(diào)用:");
            Console.WriteLine(c1.NonStaticStr);     // A 的非靜態(tài)字段
            c1.NonStaticMethod();                   // A 的非靜態(tài)方法輸出:A 的非靜態(tài)字段 | A 的非靜態(tài)屬性
            Console.WriteLine("-------------------------------\r\n");

            B b = new B();
            Console.WriteLine("使用 覆蓋了A類成員的B類對(duì)象 進(jìn)行調(diào)用:");
            Console.WriteLine(b.NonStaticStr);      // B 的非靜態(tài)字段
            b.NonStaticMethod();                    // B 的非靜態(tài)方法輸出:B 的非靜態(tài)字段
            Console.WriteLine("-------------------------------\r\n");

            A b1 = new B();
            Console.WriteLine("使用 以B類實(shí)例化的A類對(duì)象 進(jìn)行調(diào)用:");
            Console.WriteLine(b1.NonStaticStr);     // A 的非靜態(tài)字段
            b1.NonStaticMethod();                   // A 的非靜態(tài)方法輸出:A 的非靜態(tài)字段 | A 的非靜態(tài)屬性
            Console.WriteLine("-------------------------------\r\n");

            D d = new D();
            Console.WriteLine("使用 僅覆蓋了A類非靜態(tài)字段的D類對(duì)象 進(jìn)行調(diào)用:");
            Console.WriteLine(d.NonStaticStr);     // D 的非靜態(tài)字段
            d.NonStaticMethod();                   // A 的非靜態(tài)方法輸出:A 的非靜態(tài)字段 | A 的非靜態(tài)屬性
            Console.WriteLine("-------------------------------\r\n");

            E e = new E();
            Console.WriteLine("使用 僅覆蓋了A類非靜態(tài)屬性的E類對(duì)象 進(jìn)行調(diào)用:");
            Console.WriteLine(e.NoStaticProperty); // E 的非靜態(tài)屬性
            e.NonStaticMethod();                   // A 的非靜態(tài)方法輸出:A 的非靜態(tài)字段 | A 的非靜態(tài)屬性
            Console.WriteLine("-------------------------------\r\n");
        }
    }
}

@Woody 的啟發(fā):

    class AA
    {
        public virtual string NoStaticProperty { get; set; } = "AA 的非靜態(tài)虛屬性";

        public void NonStaticMethod()
        {
            Console.WriteLine($"AA 的非靜態(tài)方法輸出: 非靜態(tài)屬性:{NoStaticProperty}");
        }

    }

    class BB : AA
    {
        public override string NoStaticProperty { get; set; } = "BB 的非靜態(tài)屬性";
    }

    class CC : AA
    {
        public new string NoStaticProperty { get; set; } = "CC 的非靜態(tài)屬性";
    }
    
    //...
    
BB bb = new BB();
Console.WriteLine("使用 僅覆蓋了AA類非靜態(tài)虛屬性的BB類對(duì)象 進(jìn)行調(diào)用:");
Console.WriteLine(bb.NoStaticProperty); // BB 的非靜態(tài)屬性
bb.NonStaticMethod();                   // AA 的非靜態(tài)方法輸出: 非靜態(tài)屬性:BB 的非靜態(tài)屬性
Console.WriteLine("-------------------------------\r\n");

CC cc = new CC();
Console.WriteLine("使用 new了AA類非靜態(tài)虛屬性的CC類對(duì)象 進(jìn)行調(diào)用:");
Console.WriteLine(cc.NoStaticProperty); // CC 的非靜態(tài)屬性
cc.NonStaticMethod();                   // AA 的非靜態(tài)方法輸出: 非靜態(tài)屬性:AA 的非靜態(tài)虛屬性
Console.WriteLine("-------------------------------\r\n");

AA ab = new BB();
Console.WriteLine("使用 以BB類實(shí)例化的AA類對(duì)象 進(jìn)行調(diào)用:");
Console.WriteLine(ab.NoStaticProperty); // BB 的非靜態(tài)屬性
ab.NonStaticMethod();                   // AA 的非靜態(tài)方法輸出: 非靜態(tài)屬性:BB 的非靜態(tài)屬性
Console.WriteLine("-------------------------------\r\n");
回答
編輯回答
傻丟丟

樓主寫的例子很好呈現(xiàn)了關(guān)于這4個(gè)類的幾種用法會(huì)得到什么樣的值。

樓主首先得搞清楚重寫的概念,然后再來看這幾個(gè)例子。
其實(shí)你定義的這些方法屬性和繼承沒有關(guān)系。

首先,這個(gè)下面例子,你定義了一個(gè)B,那么獲取的任何值都會(huì)是B的值。

B b = new B();

其次,下面這個(gè)例子,你定義了一個(gè)A,那么獲取的任何值都會(huì)是A的值,不管它的實(shí)例是不是B。因?yàn)槟阍贐里面沒有重寫任何A的東西。

A b1 = new B();

你想要BCDE能覆蓋父類A的值,那么你需要override他們。應(yīng)該像下面這些寫:


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

public class B : A 
{
    public override void NonStaticMethod()
    {
        Console.WriteLine("B");
    }
}
2017年6月23日 08:00