在覆盖中向属性添加setter

为什么在实现接口时允许更改属性中getter或setter的可见性和存在?

interface IFoo { string Bar { get; } } class RealFoo : IFoo { public RealFoo(string bar) { this.Bar = bar; } public string Bar { get; private set; } } class StubFoo : IFoo { public string Bar { get; set; } } 

……在实现抽象类时,做同样的事情并不合法吗?

 abstract class AbstractFoo : IFoo { public abstract string Bar { get; } } class RealFoo : AbstractFoo { public RealFoo(string bar) { this.Bar = bar; } // Cannot override because 'Bar' does not have an overridable set accessor public override string Bar { get; private set; } } 

接口声明了类必须具有的公共属性(它只是一个契约)。 这意味着您需要拥有这些属性,但可以添加它们。

抽象类声明了这些属性的实际结构。 因此,如果您在抽象基础中没有setter,则无法在实现中添加它。
当你编写override修饰符时,它会在基类中查找要覆盖的内容。

如果你把吸气剂和制定者看作最终变成的方法,也许会变得更加清晰。

对于接口,您要定义:

 interface IFoo { string GetBar(); } 

这可以理解为“实现此接口的所有类都必须包含此方法。” 你的两个class级都做:

 class RealFoo : IFoo { public string GetBar(); private void SetBar(string value); } 

他们也实现了SetBar(),但这并不重要; 他们已经完成了界面定义的合同并且是有效的。

另一方面,抽象类是这样的:

 abstract class AbstractFoo : IFoo { public abstract string GetBar(); } 

这意味着所有子类都必须为GetBar()提供方法体

你上课的是这样的:

 class RealFoo : AbstractFoo { public override string GetBar(); public override void SetBar(string value); } 

通过将override修饰符放在SetBar方法的前面,编译器期望在基类中找到抽象或虚拟版本。 你没有,所以编译失败。

抽象类是无法实例化的类,但必须从中inheritance。 抽象类可以完全实现,但通常部分实现或根本不实现,从而封装了inheritance类的通用function。

相比之下,界面是一组完全抽象的成员,可以被认为是定义行为契约。 接口的实现完全由开发人员完成。

取自MSDN http://msdn.microsoft.com/en-us/library/scsyfw1d(v=VS.71).aspx

根据C#规范

用于实现接口的访问器可能没有accessor-modifier。 如果只使用一个访问器来实现接口,则可以使用accessor-modifier声明另一个访问器:

 public interface I { string Prop { get; } } public class C: I { public Prop { get { return "April"; } // Must not have a modifier here internal set {...} // Ok, because I.Prop has no set accessor } } 

这意味着可以在实现接口的类上修改访问权限。 但是,抽象类声明了一个实现,您无法使用派生类更改它。