在覆盖中将属性添加到属性

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修饰符时,它会在基类中查找要覆盖的内容.


Mar*_*ris 7

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

在接口的情况下,您定义了这个:

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方法的前面,编译器期望在基类中找到抽象或虚拟版本.你没有,所以编译失败.

  • 所以你间接地说C#必须添加像`public string Bar {override get; 组; 在我们实现抽象属性的方式中,我们不会受到任意限制.这实际上是有道理的. (2认同)