Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#继承概念建议_C#_Oop - Fatal编程技术网

C#继承概念建议

C#继承概念建议,c#,oop,C#,Oop,我有一个关于C#中OOP概念的小问题 我有一个界面 interface intf { string Hello(); } 基类 public class BaseClass { public string Hello() { return "Hello of base class called"; } } 派生自基类并实现接口intf的子类 public class ChildClass : BaseClass, intf { string Hell

我有一个关于C#中OOP概念的小问题

我有一个界面

interface intf
{
   string Hello();
}
基类

public class BaseClass
{
   public string Hello()
   {
      return "Hello of base class called";
   }
}
派生自
基类
并实现接口intf的子类

public class ChildClass : BaseClass, intf
{
  string  Hello()
  {
     return "Hello of child class called";
  }
}
现在我的问题是,当我创建
ChildClass
的对象时,当我调用hello方法时,它总是调用
BaseClass
的hello方法。首先,为什么它要调用
基类的
Hello
?其次,我如何调用
ChildClass
Hello

private void Form1_Load(object sender, EventArgs e)
{
      ChildClass obj = new ChildClass();
      MessageBox.Show(obj.Hello());
}

在基类
virtual
中声明方法,然后在子类中声明方法。这样,虚拟调用将解析为子类而不是父类

更新: 要回答为什么即使在方法声明中添加了
new
,它仍然是基本方法的问题,请执行以下操作:


默认情况下,类成员是私有的。因此,由于您没有将该方法标记为public,因此该方法是私有的。因此,程序被强制调用基方法,因为它是唯一可访问的方法。

按照您当前声明方法的方式,在不可访问的
ChildClass
中的方法
Hello()
,因此调用了
BaseClass
中的公共方法。您真正想要的是Esteban所说的,声明基本方法
public virtual
,派生方法
public override
,否则您的方法只是隐藏基类方法。

首先,您没有在
ChildClass
中为
Hello
提供访问修饰符。这使得它在默认情况下是私有的。要从类外部访问该方法,请将其标记为
public
(如果从同一命名空间使用,则标记为
internal
)。目前,唯一公开可见的
Hello
方法是基类方法

其次,一旦您解决了访问问题,
Hello
将在基中隐藏该方法。如果这是有意的,建议在方法中使用
new
关键字

public new string Hello()
如果您的意图不是隐藏该方法,而是重写它,请在基类中将该方法标记为virtual,并在子类中使用override关键字

public class ChildClass : BaseClass, intf
{
    public override string Hello()
    {
        return "Hello of child class called";
    }
}

public class BaseClass
{
    public virtual string Hello()
    {
        return "Hello of base class called";
    }
}
这将允许您始终调用子方法,除非您从子方法中显式调用基方法

来自外部世界的类似呼叫

((BaseClass)child).Hello();
(child as BaseClass).Hello();
BaseClass baseClass = new ChildClass();
baseClass.Hello();
将导致使用子方法

在子类中进行类似这样的调用

base.Hello();

将导致使用基类方法。

为什么要调用base的Hello

您的子类实现了接口,因此它被认为包含一个公共Hello方法。但是在你的孩子课堂上,Hello不是公开的。基类中的Hello方法是公共的,被认为是接口的实现

如何呼叫儿童班的Hello

public class BaseClass
{
   public string Hello()
   {
      return "Hello of base class called";
   }
}

在儿童课上公开打招呼。然后,它将被视为接口的一个实现。

正如其他人所说的,将子类中的Hello方法设置为public override


此外,IMHO,您应该在基类中实现接口,而不是在子类中实现接口。但是这与您的方法没有被调用这一事实无关。

为什么还要在接口上声明该方法呢?你想完成什么?另外,你知道你可以显式实现一个接口吗?我只是想学习conepts,是的,我知道如果我使用intf.hello,这将调用我的接口方法。谢谢回复。所以,子类上的方法应该是
public
Esteban,谢谢回复,我同意当我使用virtual和override关键字时,它会调用child的hello。现在,让我稍微修改一下代码,并将新关键字添加到我的子类hello键中,如果我现在检查它,它仍然调用base的hello。为什么?在生成项目时检查错误和警告。如果您的
virtual
override
关键字不正确,您将收到类似这样的警告:“'App.ChildClass.Hello()'隐藏继承的成员'App.BaseClass.Hello()'。如果要隐藏,请使用新关键字。”