解释继承方法重写
本文关键字:重写 方法 继承 解释 | 更新日期: 2023-09-27 18:35:42
这里有两个类:
public class ClassA
{
public string result()
{
return "ClassA_Result";
}
}
和
public class ClassB : ClassA
{
public string result()
{
return "ClassB_Result";
}
}
当我创建 ClassB 的实例时,我得到的结果是 ClassB_Result
.我希望结果会ClassA_Result
ClassB objB = new ClassB();
string b = objB.result(); //result is `ClassB_Result`
首先,你没有覆盖result()
方法——事实上你不能,因为它不是虚拟的。
编译器应该给你一个这样的警告:
警告 CS0108: "ClassB.result()" 隐藏继承的成员 'ClassA.result()'。如果要隐藏,请使用 new 关键字。
始终阅读编译器警告。他们在那里帮助你。
您应该在 ClassA
中对方法有一个 virtual
修饰符,在 ClassB
中对方法有一个override
修饰符。我还鼓励您遵循 .NET 命名约定 - 我知道这只是一个示例,但即使在虚拟代码中也值得遵循约定。(result
应该是Result
。
现在,即使您已经像这样修复了代码,您仍然会得到ClassB_Result
- 因为您正在创建ClassB
的实例。如果你写:
ClassA objB = new ClassB();
string b = objB.result();
使用该代码片段,在当前代码中,它将给出ClassA_Result
的结果,因为该方法不是虚拟调用的。使用固定代码,它将给出ClassB_Result
的结果,因为将调用 ClassB
中的覆盖。目前,您在ClassA
中的方法完全无关紧要,因为objB
的编译时类型是 ClassB
。
或者在 B 类中使用 new 关键字
public class ClassB : ClassA
{
new public string result()
{
return "ClassB_Result";
}
}
来自 MSDN -"用作声明修饰符时,new 关键字显式隐藏从基类继承的成员。隐藏继承的成员时,成员的派生版本将替换基类版本。尽管可以在不使用新修饰符的情况下隐藏成员,但会收到编译器警告。如果使用 new 显式隐藏成员,则会禁止显示此警告。http://msdn.microsoft.com/en-us/library/435f1dw2.aspx
你所做的是方法隐藏而不是方法覆盖,
使用带有方法隐藏的A类和B类的定义,下面的代码将得到"ClassB_Result"
ClassB objB = new ClassB();
string b = obj.result();
但下面会得到"ClassA_Result"
ClassA obj = new ClassB();
string a = obj.result();
但是对于方法重写,您的类定义需要稍微更改一下,在类 A 中,方法应标记为"虚拟",而在类 B 中,相同的方法应标记为覆盖。
使用方法覆盖时,下面的两个代码片段将仅获得"ClassB_Result"。
ClassB objB = new ClassB();
string b = obj.result();
和
ClassA obj = new ClassB();
string a = obj.result();