将设置器添加到覆盖中的属性

发布于 2024-11-09 02:44:55 字数 683 浏览 0 评论 0原文

为什么在实现接口时允许更改属性中 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; }
}

Why is it allowed to change the visibility and existence of getters or setters in a property when implementing an interface?

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; }
}

...and not legal to do the same when implementing an abstract class?

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; }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

心如狂蝶 2024-11-16 02:44:55

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

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

The interface declares what public properties the class must have (It's just a contract). Which means you need to have those properties, but can add to them.

The abstract class declares the actual structure of those properties. So if you don't have the setter in the abstract base, you can't add to it in the implementation.
When you write the override modifier it looks in the base class for something to override.

半山落雨半山空 2024-11-16 02:44:55

如果您将 getter 和 setter 视为它们最终成为的方法,情况可能会变得更清楚。

对于接口,您定义的是:

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 方法前面基类中的抽象或虚拟版本。你没有这个,所以编译失败。

It perhaps becomes clearer if you think of the getters and setters as the methods that they eventually become.

In the case of the interface you are defining this:

interface IFoo
{
    string GetBar();
}

Which can be read as "all classes that implement this interface must include this method."
Both of your classes do:

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

they also implement SetBar(), but that is immaterial; they have fulfilled the contract defined by the interface and are valid.

The abstract class, on the other hand is this:

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

Which means that all child classes must provide a method body for GetBar()

The class you made is this:

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

By putting the override modifier in front of the SetBar method the compiler is expecting to find an abstract or virtual version in the base class. You don't have that so the compilation fails.

请帮我爱他 2024-11-16 02:44:55

抽象类是不能实例化但必须继承的类。抽象类可以完全实现,但更常见的是部分实现或根本不实现,从而封装继承类的公共功能。

相比之下,接口是一组完全抽象的成员,可以将其视为定义行为契约。接口的实现完全留给开发人员。

摘自MSDN
http://msdn.microsoft.com/en-我们/库/scsyfw1d(v=VS.71).aspx

An abstract class is a class that cannot be instantiated, but must be inherited from. An abstract class may be fully implemented, but is more usually partially implemented or not implemented at all, thereby encapsulating common functionality for inherited classes.

An interface, by contrast, is a totally abstract set of members that can be thought of as defining a contract for conduct. The implementation of an interface is left completely to the developer.

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

傲娇萝莉攻 2024-11-16 02:44:55

根据C#规范

用于实现的访问器
接口可能没有
访问器修饰符。如果只有一个
访问器用于实现
接口,其他访问器可能是
使用访问器修饰符声明:

公共接口I
{
  字符串属性 { get; }
}
公开课C:I
{
  公共道具 {
  得到{返回“四月”; } // 这里不能有修饰符
        Internal set {...} // 好的,因为 I.Prop 没有 set 访问器
  }
}

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

According to the C# specification

An accessor that is used to implement
an interface may not have an
accessor-modifier. If only one
accessor is used to implement an
interface, the other accessor may be
declared with an 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
  }
}

That means it is OK to have an access modified on a class implementing the interface. However, the abstract class declares an implementation and you cannot change that with a derived class.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文