关于C#OOPS虚拟/覆盖关键字使用情况

时间:2013-12-16 14:52:47

标签: c# oop

只看到这个程序

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)如何使用具有相同名称的函数。类A具有foo()函数,类b具有foo()函数,当类b进入A.当类b扩展a然后通过继承类时,b得到了名为foo()的函数。为什么上面的代码运行没有任何错误?

2)

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

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

我们是否正在创建B的实例,如果是,那么当我们写a.Foo()然后foo()函数的类b应该调用但是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()"
            }
        }

所以请解释一下幕后发生的事情。感谢

3 个答案:

答案 0 :(得分:2)

  

当类b扩展a然后继承类时,b得到了一个名为foo()的函数。为什么上面的代码运行没有任何错误?

因为B中的成员只是隐藏 A中的成员。

  

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

B实施A以来,您正在创建B的实例,并在其他地方使用时将其键入A。这就是为什么要调用类A中的函数而不是B

  

当我们添加virtual / override关键字时,会调用类b的foo()函数。

此处调用B的原因是因为它实际上覆盖 A的功能。

答案 1 :(得分:1)

  

为什么上面的代码运行没有任何错误?

它会发出警告:'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()函数是   被称为为什么?

您正在Foo变量上调用A。因此,即使此A实例实际上是B类型,您也要在A类型的变量上调用方法。

答案 2 :(得分:0)

在第二个示例中,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();