C# 中的重写方法
Overriding methods in C#
在学习了 Java 整个学期后,我目前正在自学 C#。
java(或一般的面向对象编程)的一个特性是能够覆盖继承到子类中的方法。
我在研究 C# 中的此功能时,在没有研究 C# 中重写方法的正确方法的情况下,尝试自己重写一个方法,并且似乎可行。
然而,经过进一步研究,我了解到我们需要在超类中声明方法时使用关键字virtual
,在子类中重写方法时使用override
。
所以我的问题是:
在 C# 中覆盖方法的正确方法是什么?
补充说明:我也想知道同样的情况是否适用于 C# 中的重载方法。
以下摘自维基百科(参见here,C#部分)。
“C# 确实支持方法覆盖,但前提是使用修饰符 override
和 virtual
或 abstract
. *)
abstract class Animal {
public String Name {get; set; }
// Methods
public void Drink();
public virtual void Eat();
public void Go();
}
class Cat : Animal {
public new String Name {get; set; }
// Methods
public void Drink(); // warning: hides inherited drink(). Use new
public override void Eat(); // overrides inherited eat().
public new void Go(); // hides inherited go().
}
当用一个方法覆盖另一个方法时,这两个方法的签名必须相同(并且具有相同的可见性)。在 C# 中,class 方法、索引器、属性和事件都可以被覆盖。"
*) 正如bradbury9正确提到的,维基百科页面有错误,所以我稍微更改了答案(添加了上面的粗体文本)
在 .net 中有两种不同的覆盖方法,具体取决于您是否要提供默认实现。
- virtual keyword 确实提供了默认实现。
- abstract keyword 仅声明必须从继承 class 的那些 class 中覆盖它的内容。只能在
abstract
classes. 里面使用
还有其他与继承相关的关键字,例如:
- sealed keyword说class是final的,不能继承
- override keyword 它表示该元素正在覆盖父
abstract
或 virtual
元素。
示例:
public abstract class Bank
{
public abstract string Country { get; } // Everything inheriting must implement it
public virtual decimal TaxPercent { get { return 0.25; } } // Implementing it is optional
public decimal DeclareTaxes()
{
decimal taxesToPay = 4000 * TaxPercent;
return taxesToPay;
}
}
public sealed class BahamasBank: Bank
{
public override string Country { get { return "Bahamas"; }
public override TaxPercent { get { return 0.0; } } // Bahamas is different from most countries in tax related stuff
}
public sealed class CanadaBank: Bank
{
public override string Country { get { return "Canada"; }
}
在学习了 Java 整个学期后,我目前正在自学 C#。
java(或一般的面向对象编程)的一个特性是能够覆盖继承到子类中的方法。
我在研究 C# 中的此功能时,在没有研究 C# 中重写方法的正确方法的情况下,尝试自己重写一个方法,并且似乎可行。
然而,经过进一步研究,我了解到我们需要在超类中声明方法时使用关键字virtual
,在子类中重写方法时使用override
。
所以我的问题是:
在 C# 中覆盖方法的正确方法是什么?
补充说明:我也想知道同样的情况是否适用于 C# 中的重载方法。
以下摘自维基百科(参见here,C#部分)。
“C# 确实支持方法覆盖,但前提是使用修饰符 override
和 virtual
或 abstract
. *)
abstract class Animal {
public String Name {get; set; }
// Methods
public void Drink();
public virtual void Eat();
public void Go();
}
class Cat : Animal {
public new String Name {get; set; }
// Methods
public void Drink(); // warning: hides inherited drink(). Use new
public override void Eat(); // overrides inherited eat().
public new void Go(); // hides inherited go().
}
当用一个方法覆盖另一个方法时,这两个方法的签名必须相同(并且具有相同的可见性)。在 C# 中,class 方法、索引器、属性和事件都可以被覆盖。"
*) 正如bradbury9正确提到的,维基百科页面有错误,所以我稍微更改了答案(添加了上面的粗体文本)
在 .net 中有两种不同的覆盖方法,具体取决于您是否要提供默认实现。
- virtual keyword 确实提供了默认实现。
- abstract keyword 仅声明必须从继承 class 的那些 class 中覆盖它的内容。只能在
abstract
classes. 里面使用
还有其他与继承相关的关键字,例如:
- sealed keyword说class是final的,不能继承
- override keyword 它表示该元素正在覆盖父
abstract
或virtual
元素。
示例:
public abstract class Bank
{
public abstract string Country { get; } // Everything inheriting must implement it
public virtual decimal TaxPercent { get { return 0.25; } } // Implementing it is optional
public decimal DeclareTaxes()
{
decimal taxesToPay = 4000 * TaxPercent;
return taxesToPay;
}
}
public sealed class BahamasBank: Bank
{
public override string Country { get { return "Bahamas"; }
public override TaxPercent { get { return 0.0; } } // Bahamas is different from most countries in tax related stuff
}
public sealed class CanadaBank: Bank
{
public override string Country { get { return "Canada"; }
}