只需查看此程序
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() { ... }
或者按照您的说明使用virtual
和override
。
为什么上面的代码运行时没有任何错误?
它会产生警告:'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();