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



只需查看此程序

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()的含义是什么?

如果是的话,那么当我们写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

如果您打算在B中覆盖Foo的功能,那么您可以在B中使用new关键字:

public new void Foo() { ... }

或者按照您的说明使用virtualoverride

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

它会产生警告:'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();

最新更新