簡體   English   中英

關於C#OOPS虛擬/替代關鍵字的用法

[英]Regarding C# OOPS virtual/override keyword usage

只看這個程序

class A
        {
              public void Foo() { Console.WriteLine("A::Foo()"); }
        }

        class B : A
        {
              public void Foo() { Console.WriteLine("B::Foo()"); }
        }

        class Test
        {
            static void Main(string[] args)
            {
                A a;
                B b;

                a = new A();
                b = new B();
                a.Foo();  // output --> "A::Foo()"
                b.Foo();  // output --> "B::Foo()"

                a = new B();
                a.Foo();  // output --> "A::Foo()"
            }
        }

1)如何分類可以具有同名的功能。 當類b進入A時,類A具有foo()函數,而類b具有foo()函數。當類b擴展a時,通過繼承,類b獲得了稱為foo()的函數。 為什么上面的代碼運行沒有任何錯誤?

2)

        a = new B();
        a.Foo();  // output --> "A::Foo()"

a = new B()是什么意思?

我們是否在創建B的實例(如果是),那么當我們編寫a.Foo()時,應該調用b類的foo()函數,但是卻調用了a類的foo()函數,為什么?

當我們添加virtual / override關鍵字時,將調用類b的foo()函數。

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

        class B : A
        {
            public override void Foo() { Console.WriteLine("B::Foo()"); }
        }

        class Test
        {
            static void Main(string[] args)
            {
                A a;
                B b;

                a = new A();
                b = new B();
                a.Foo();  // output --> "A::Foo()"
                b.Foo();  // output --> "B::Foo()"

                a = new B();
                a.Foo();  // output --> "B::Foo()"
            }
        }

所以請解釋一下幕后發生的事情。 謝謝

當類b擴展a時,通過繼承類b獲得了名為foo()的函數。 為什么上面的代碼運行沒有任何錯誤?

因為B中的成員只是將成員隱藏A

a = new B()是什么意思?

由於B實現A ,因此您將創建B的實例,並在其他任何地方使用它時將其鍵入為A 這就是為什么要調用類A的函數而不是B

當我們添加virtual / override關鍵字時,將調用類b的foo()函數。

之所以在這里調用B是因為,實際上它覆蓋A的功能。

當您聲明具有相同名稱的方法時,它將隱藏該方法。

如果要調用繼承的方法,可以執行以下操作:

var b = new B();

var casted = (A)b;

casted.Foo(); // will call A.Foo

如果你的目的是覆蓋的功能FooB ,那么你可以使用new內關鍵字B

public new void Foo() { ... }

或者按照您的說明使用virtualoverride

為什么上面的代碼運行沒有任何錯誤?

它產生警告: 'B.Foo()' hides inherited member 'A.Foo()'. Use the new keyword if hiding was intended. 'B.Foo()' hides inherited member 'A.Foo()'. Use the new keyword if hiding was intended.

因此,編譯器會警告您潛在的錯誤,但這是有效的,並且B.Foo方法隱藏了A.Foo一個。

我們是否在創建B的實例(如果是),那么當我們編寫a.Foo()時,應該調用b類的foo()函數,但是卻調用了a類的foo()函數,為什么?

您正在A變量上調用Foo 所以,即使這A實例實際上B型的是,你調用類型的變量的方法A

在第二個示例中, B.Foo 覆蓋 A.Foo ,這意味着該方法的邏輯已被替換

在第一個示例中, B.Foo 隱藏了 A.Foo的實現。 不涉及繼承。 因此,如果類型A的變量包含類型B的實例(即A a = new B(); ),則將使用A的實現。


我們可以直接創建b的實例並調用foo(),但是為什么人們寫這樣的代碼A a = new B()然后調用a.foo()呢? 編寫這種代碼可以實現什么樣的目標。 謝謝

不問自己為什么要寫A a=new B() ,而是問自己:為什么要使用new方法?

原因之一可能是要克服無法覆蓋A.Foo的事實,因為它沒有被標記為虛擬的。 假設您獲得了A類,該類在無法修改的第三方程序集中實現。 如果使用您自己的類B擴展該類,則使用new方法隱藏其實現,並寫成B b = new B(); b.Foo(); B b = new B(); b.Foo();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM