[英]Overwriting a property's accessors
我馬上就跳進來。
假設AudioFile是一個抽象類,如下所示:
abstract class AudioFile
{
public string Title { get; set; }
}
現在,在大多數情況下,使用a.Title非常適合從AudioFile繼承的其他類。 但是,在MPEG文件的情況下,它存儲在id3變量中的不同對象中:
class MPEG : AudioFile
{
private ID3 id3;
public new string Title {
get {
return id3.Title;
}
set {
id3.Title = value;
}
}
}
class WMA : AudioFile
{
}
我想要的是做以下事情:
AudioFile a;
if( isMPEG ) {
a = LoadMPEG(); // Returns a new MPEG instance.
} else
if( isWMA ) {
a = LoadWMA(); // Return a new WMA instance.
}
Console.WriteLine( a.Title );
// Other stuff with a.
我希望輸出是歌曲的標題,無論是MPEG還是WMA。 但是,當它的MPEG時,它不能按預期工作(因為它沒有使用id3對象)。 它的唯一工作方式是:
if( isMPEG ) {
MPEG a = LoadMPEG(); // Returns a new MPEG instance.
Console.WriteLine( a.Title );
// Other stuff with a.
} else
if( isWMA ) {
WMA a = LoadWMA(); // Return a new WMA instance.
Console.WriteLine( a.Title );
// Other stuff with a.
}
這不是我想要的。 關於如何做我想做的事情的想法?
使抽象類屬性為virtual
以便派生類在需要不同行為時可以覆蓋它。
abstract class AudioFile
{
public virtual string Title { get; set; }
}
class MpegFile : AudioFile
{
public override string Title { /* your custom getter and setter */ }
}
AudioFile file = new MpegFile();
string title = file.Title; // will use override
在您的版本中,您將抽象類屬性保留為非虛擬,並將派生類屬性標記為new
。 這允許您僅通過派生類的引用來使用自定義行為。 您失去了通過基礎體驗多態行為的能力。 new
修飾符僅通過派生引用隱藏基本行為。 基本引用使用基本行為。
AudioFile file = new MPEG(); // will use base behavior for non-virtual methods
MPEG file = new MPEG(); // will use derived behavior when non-virtual methods are hidden by new
您可能碰巧來自Java背景。 在C#中,默認情況下成員不是虛擬的。 您必須將它們標記為virtual
,並使用override
以多態方式替換或擴充基本實現。 (對於抽象類中的抽象成員,您可以使用關鍵字abstract
而不是virtual
。)當基本方法不是虛擬的時, new
關鍵字很有用,但您已經看到了它的局限性。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.