class Parent
{
public void foo()
{
Console.WriteLine("Hello from the foo inside Parent");
}
public virtual void bar()
{
Console.WriteLine("Hello from the bar inside Parent.");
}
public void foobar()
{
Console.WriteLine("Hello from the foobar inside Parent.");
}
}
class Child : Parent
{
public void foo()
{
base.foo();
Console.WriteLine("Hello from the foo inside Child");
}
public override void bar()
{
base.bar();
Console.WriteLine("Hello from the bar inside Child.");
}
public new void foobar()
{
base.foobar();
Console.WriteLine("Hello from the foobar inside Child.");
}
}
上面是我用来测试我在 C# 中的继承知识的代码,但我在这里有一个困惑:
- 子函数
foo()
隐藏了父函数的foo()
。 - 子函数
bar()
隐藏了父函数的bar()
。 - 函数
foobar()
隐藏了 parent() 的bar()
所有这三个函数都使用不同的技术来隐藏父函数。任何人都可以指导我,这三个之间有什么区别,什么时候使用哪个?
最佳答案
首先,1 和 3 是相同的,编译器/IDE (Visual Studio) 会自动假定您打算在执行第 1 项时执行第 3 项。您会注意到它在名称 foo 下放置了一条绿线()
并告诉您使用 new
关键字。所以在现实中,只有两种类型的基于继承的方法改变:
- 方法覆盖
- 方法隐藏
方法覆盖是指一个类将其方法声明为虚拟方法,这实质上是说“任何继承 self 的类都可以自由覆盖它”。这意味着无论如何,如果子类重写该方法,将调用重写的版本。
另一方面,方法隐藏是 child 叛逆并说“只要我作为子类存在,我就会忽略我的父实现并改为执行此操作”。这里的技巧是,当子类被视为其父类时,将调用父类的实现。
这是一个示例,假设正在使用您的类(class)设置:
Child c = new Child();
c.foo();
c.bar();
Parent p = c;
p.foo();
p.bar();
请注意,Child c
可以存储在父变量中,因为它具有继承性。
任何从父类继承的子类都可以视为其父类的实例。
现在尝试将此类添加到组合中:
class MaleChild : Parent
{
public new void foo()
{
base.foo();
Console.WriteLine("Hello from the foo inside MaleChild");
}
public override void bar()
{
base.bar();
Console.WriteLine("Hello from the bar inside MaleChild.");
}
}
并运行类似的测试:
Parent[] p = new Parent[2];
p[0] = new Child();
p[1] = new MaleChild();
p[0].foo();
p[0].bar();
p[1].foo();
p[1].bar();
现在您看到,即使两个继承类都被视为它们的父类,重写的方法对于继承类也是唯一的。这允许父类定义其工作方式的基本轮廓,而子类则对其进行细化并更具体地做事。然而,因为子类可以做父类可以做的所有事情,所以它可以被视为父类。
这个概念被称为多态性。
关于C# 函数的继承和重写,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17520837/