【问题标题】:new Keyword and Method Hiding新的关键字和方法隐藏
【发布时间】:2015-05-13 07:19:11
【问题描述】:

new 关键字用于隐藏相同的基类实现。但我不知道为什么下面的代码产生输出作为基类

class Baseclass
{ 
    public void fun()
    { 
        Console.Write("Base class" + " ");
    } 
} 
class Derived1: Baseclass
{ 
    new void fun()
    {
        Console.Write("Derived1 class" + " "); 
    } 
} 
class Derived2: Derived1
{ 
    new void fun()
    { 
        Console.Write("Derived2 class" + " ");
    }
}
class Program
{ 
    public static void Main(string[ ] args)
    { 
        Derived2 d = new Derived2(); 
        d.fun(); 
    } 
} 

我们在derived2中隐藏了fun的实现,但仍然调用Base类,为什么会这样?我错过了什么吗?

【问题讨论】:

  • 您的方法具有不同的可见性(公共与私有)

标签: c# inheritance


【解决方案1】:

Derived2.fun是私有的(它是该类型成员的默认访问修饰符)。它在课堂外是不可见的。只有类外可见的fun方法是Baseclass.fun,因此会被调用。

您需要让您的Derived2.fun 在课堂外可见以获得预期的输出。您可以通过将其设为公开/内部来做到这一点。

【讨论】:

  • 好地方!您还应该解释 为什么 Derived2.fun 是私有的
【解决方案2】:

通常,隐藏在 C# 中的工作方式如下:“hider”(方法或字段或使用 new 关键字声明的任何内容)从“隐藏”的内容中接管所有“功能”。例如:

class Baseclass
{ 
    public void fun()
    { 
        Console.Write("Base class" + " ");
    } 
} 
class Derived1 : Baseclass
{ 
    new public void fun()
    {
        Console.Write("Derived1 class" + " "); 
    } 
}

这里,Derived1 中的fun 完全隐藏了Baseclass 中的fun,因为它们具有完全相同的“功能”:它们都是方法,并且都是public,即在任何地方都可用。

但是,如果“隐藏”成员没有涵盖“隐藏”成员的所有功能,它仍然会在那里,准备好完成它的工作。示例:

class Baseclass
{ 
    public void fun()
    { 
        Console.Write("Base class" + " ");
    } 
} 
class Derived1 : Baseclass
{ 
    new public int fun;
}

这里,Baseclass.fun 是一个方法,Derived1.fun 是一个字段。

您可以访问赋值表达式中的“隐藏”字段,如下所示:int a = new Derived1().fun;。由于它隐藏了基类方法fun,因此您无法通过这种方式访问​​它(方法):System.Action a = new Derived1().fun; 失败。

但是,如果我们对fun 做一些int 字段不能做的事情会发生什么? new Derived1().fun(); 可以工作,在基类中调用 fun

这个具体的例子甚至在 MSDN 上的 new Modifier page 上提到:

通常,在类或结构中引入的常量、字段、属性或类型会隐藏与其名称相同的所有基类成员。有特殊情况。例如,如果您声明一个名为 N 的新字段具有不可调用的类型,并且基类型将 N 声明为方法,则新字段不会在调用语法中隐藏基声明。

您的情况非常相似。您的两个派生类中的 fun 方法仅隐藏了基类中原始 fun 的一部分。如果您从Derived1Derived2 内部调用fun,您将得到相应类的foo 的“隐藏”版本。但是,当您从三个类之外调用foo 时,会调用Baseclasspublic 方法,因为它的public 功能没有被隐藏...

【讨论】:

  • 但是为什么要使用“new”关键字呢?在我的实验中,无论有没有它,它的功能都相同。唯一的区别是编译器警告。
猜你喜欢
  • 1970-01-01
  • 2022-01-20
  • 2015-04-19
  • 1970-01-01
  • 1970-01-01
  • 2010-11-13
  • 1970-01-01
  • 2013-01-16
  • 1970-01-01
相关资源
最近更新 更多