C# 函数的继承和重写

标签 c# inheritance

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# 中的继承知识的代码,但我在这里有一个困惑:

  1. 子函数 foo() 隐藏了父函数的 foo()
  2. 子函数bar()隐藏了父函数的bar()
  3. 函数 foobar() 隐藏了 parent() 的 bar()

所有这三个函数都使用不同的技术来隐藏父函数。任何人都可以指导我,这三个之间有什么区别,什么时候使用哪个?

最佳答案

首先,1 和 3 是相同的,编译器/IDE (Visual Studio) 会自动假定您打算在执行第 1 项时执行第 3 项。您会注意到它在名称 foo 下放置了一条绿线() 并告诉您使用 new 关键字。所以在现实中,只有两种类型的基于继承的方法改变:

  1. 方法覆盖
  2. 方法隐藏

方法覆盖是指一个类将其方法声明为虚拟方法,这实质上是说“任何继承 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/

相关文章:

Java方法: retrieve the inheriting type

c++ - 从父方法调用子方法

c# - 本地游戏对象变量不能使用 switch 方法 (Unity)

c# - WPF 在使用 dotfuscator 后抛出异常?

c# - 查找 int[] 数组的所有可能组合,在 C# 中受长度限制

oop - Lua类继承问题

C++ 将指针从一个派生类转换为另一个派生类

c# - 立即更新 toolStripStatusLabel

c# - 当鼠标悬停在内部 ListView 上时,ListView 内的 WPF ListView 不滚动

java - 只允许某些类访问私有(private)变量的接口(interface)