C# 覆盖属性';s存取器
我马上跳进去 假设AudioFile是一个抽象类,如下所示:C# 覆盖属性';s存取器,c#,inheritance,C#,Inheritance,我马上跳进去 假设AudioFile是一个抽象类,如下所示: 抽象类音频文件 { 公共字符串标题{get;set;} } 现在,在大多数情况下,使用.Title非常适合于从AudioFile继承的其他类。但是,对于MPEG文件,它存储在id3变量中的不同对象中: class-MPEG:AudioFile { 私人ID3 ID3; 公共新字符串标题{ 得到{ 返回id3.标题; } 设置{ id3.标题=价值; } } } WMA类:音频文件 { } 我想做的是: a音频文件; 如果(isMP
抽象类音频文件
{
公共字符串标题{get;set;}
}
现在,在大多数情况下,使用.Title非常适合于从AudioFile继承的其他类。但是,对于MPEG文件,它存储在id3变量中的不同对象中:
class-MPEG:AudioFile
{
私人ID3 ID3;
公共新字符串标题{
得到{
返回id3.标题;
}
设置{
id3.标题=价值;
}
}
}
WMA类:音频文件
{
}
我想做的是:
a音频文件;
如果(isMPEG){
a=LoadMPEG();//返回一个新的MPEG实例。
}否则
如果(isWMA){
a=LoadWMA();//返回一个新的WMA实例。
}
控制台。书写线(a.标题);
//其他有a的东西。
我希望输出是歌曲的标题,无论是MPEG还是WMA。但是,当它使用MPEG时,它不能按预期工作(因为它没有使用id3对象)。唯一可行的方法是:
if(isMPEG){
MPEG a=LoadMPEG();//返回一个新的MPEG实例。
控制台。书写线(a.标题);
//其他有a的东西。
}否则
如果(isWMA){
WMA=LoadWMA();//返回一个新的WMA实例。
控制台。书写线(a.标题);
//其他有a的东西。
}
这不是我想要的。关于如何做我想做的事情的想法?使抽象类属性
虚拟化
,以便派生类可以在需要不同行为时重写它
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
在基本方法不是virtual时很有用,但您已经看到了它的局限性。很好的答案,效果非常好。谢谢是的,我确实有Java背景。:)