nde*_*uma 16 c# properties abstract
为什么在实现接口时允许更改属性中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; }
}
Run Code Online (Sandbox Code Playgroud)
......在实现抽象类时,做同样的事情并不合法吗?
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; }
}
Run Code Online (Sandbox Code Playgroud)
Yoc*_*mer 12
接口声明了类必须具有的公共属性(它只是一个契约).这意味着您需要拥有这些属性,但可以添加它们.
抽象类声明了这些属性的实际结构.因此,如果您在抽象基础中没有setter,则无法在实现中添加它.
当您编写override修饰符时,它会在基类中查找要覆盖的内容.
如果你把吸气剂和制定者看作最终变成的方法,也许会变得更加清晰.
在接口的情况下,您定义了这个:
interface IFoo
{
string GetBar();
}
Run Code Online (Sandbox Code Playgroud)
这可以理解为"实现此接口的所有类都必须包含此方法." 你的两个课都做:
class RealFoo : IFoo
{
public string GetBar();
private void SetBar(string value);
}
Run Code Online (Sandbox Code Playgroud)
他们还实现了SetBar(),但这并不重要; 他们已经完成了界面定义的合同并且是有效的.
另一方面,抽象类是这样的:
abstract class AbstractFoo : IFoo
{
public abstract string GetBar();
}
Run Code Online (Sandbox Code Playgroud)
这意味着所有子类都必须为GetBar()提供方法体
你上课的是这样的:
class RealFoo : AbstractFoo
{
public override string GetBar();
public override void SetBar(string value);
}
Run Code Online (Sandbox Code Playgroud)
通过将override修饰符放在SetBar方法的前面,编译器期望在基类中找到抽象或虚拟版本.你没有,所以编译失败.