覆盖房产的评估员

时间:2011-10-21 02:15:26

标签: c# inheritance

我马上就跳进来。

假设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.
}

这不是我想要的。关于如何做我想做的事的想法?

1 个答案:

答案 0 :(得分:4)

创建抽象类属性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关键字很有用,但您已经看过它限制。