只看到这个程序
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()"
}
}
所以请解释一下幕后发生的事情。感谢
答案 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();