为什么在实现接口时允许更改属性中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; }
}
答案 0 :(得分:12)
接口声明了类必须具有的公共属性(它只是一个契约)。这意味着你需要拥有这些属性,但可以添加它们。
抽象类声明了这些属性的实际结构。因此,如果您没有抽象基础中的setter,则无法在实现中添加它 当你编写覆盖修饰符时,它会在基类中查找要覆盖的内容。
答案 1 :(得分:7)
如果你认为吸气剂和制定者最终会变成它们的方法,那么它可能会变得更加清晰。
对于界面,您要定义:
interface IFoo
{
string GetBar();
}
可以将其视为“实现此接口的所有类必须包含此方法。” 你的两个课都这样做:
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方法的前面,编译器期望在基类中找到抽象或虚拟版本。你没有,所以编译失败。
答案 2 :(得分:0)
抽象类是一个无法实例化但必须继承的类。抽象类可以完全实现,但通常部分实现或根本不实现,从而封装了继承类的通用功能。
相比之下,界面是一组完全抽象的成员,可以被认为是定义行为契约。接口的实现完全留给开发人员。取自MSDN http://msdn.microsoft.com/en-us/library/scsyfw1d(v=VS.71).aspx
答案 3 :(得分:0)
根据C#规范
用于实现的访问者 界面可能没有 访问修饰符。如果只有一个 accessor用于实现 接口,其他访问者可能是 使用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 } }
这意味着可以在实现接口的类上修改访问权限。但是,抽象类声明了一个实现,您无法使用派生类更改它。