C#继承概念建议
我有一个关于C#中OOP概念的小问题 我有一个界面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
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()'。如果要隐藏,请使用新关键字。”