为什么我不能拥有受保护的接口成员? [英] Why can't I have protected interface members?

查看:26
本文介绍了为什么我不能拥有受保护的接口成员?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

反对在接口上声明受保护访问成员的论据是什么?例如,这是无效的:

What is the argument against declaring protected-access members on interfaces? This, for example, is invalid:

public interface IOrange
{
    public OrangePeel Peel { get; }
    protected OrangePips Seeds { get; }
}

在这个例子中,接口 IOrange 将保证实现者至少向他们的继承者提供一个 OrangePips 实例.如果实现者愿意,他们可以将范围扩展到完整的public:

In this example, the interface IOrange would guarantee that implementors at least provide an OrangePips instance to their inheritors. If the implementor wanted to, they could expand the scope to full public:

public class NavelOrange : IOrange
{
    public OrangePeel Peel { get { return new OrangePeel(); } }
    protected OrangePips Seeds { get { return null; } }
}

public class ValenciaOrange : IOrange
{
    public OrangePeel Peel { get { return new OrangePeel(); } }
    public OrangePips Seeds { get { return new OrangePips(6); } }
}

接口上protected成员的意图是为继承者(子类)提供支持契约,例如:

The intent of protected members on interfaces is to provide a support contract for inheritors (sub-classes), for example:

public class SpecialNavelOrange : NavelOrange
{
    ...
    // Having a seed value is useful to me.
    OrangePips seeds = this.Seeds; 
    ...
}

(诚然,这不适用于 structs)

(Admittedly, this wouldn't work for structs)

我看不到接口中 privateinternal 修饰符的情况,但同时支持 publicprotected 修饰符似乎完全合理.

I can't see much of a case for private or internal modifiers in interfaces, but supporting both public and protected modifiers seems perfectly reasonable.

我将尝试通过将 interfaceinterface 完全分开来解释 protected 成员在 interface 上的效用:

I'm going to try explaining the utility of protected members on interfaces by separating them from interfaces entirely:

让我们想象一个新的 C# 关键字 support 来强制继承者契约,以便我们声明如下:

Let's imagine a new C# keyword, support, to enforce inheritor contracts, so that we declare things as follows:

public support IOrangeSupport
{
    OrangePips Seeds { get; }
}

这将允许我们收缩类以向其继承者提供受保护的成员:

This would allows us to contract classes to provide protected members to their inheritors:

public class NavelOrange : IOrange, IOrangeSupport
{
    public OrangePeel Peel { get { return new OrangePeel(); } }
    protected OrangePips Seeds { get { return null; } }
}

这不是特别有用,因为类已经通过首先提供 protected 成员来暗示这个契约.

This is not particularly useful, because classes would already imply this contract by providing the protected members in the first place.

但是我们也可以这样做:

But then we could also do this:

public interface IOrange : IOrangeSupport
{
   ...
}

从而将 IOrangeSupport 应用于所有实现 IOrange 的类,并要求它们提供特定的 protected 成员 - 这不是我们目前可以做的.

Thereby applying IOrangeSupport to all classes which implement IOrange and requiring them to provide particular protected members - which is not something we can currently do.

推荐答案

我想每个人都认为接口只有公共成员,没有实现细节.您正在寻找的是抽象类.

I think everyone hammered the point of an interface having only public members, no implementation details. What you are looking for is an abstract class.

public interface IOrange
{
    OrangePeel Peel { get; }
}

public abstract class OrangeBase : IOrange
{
    protected OrangeBase() {}
    protected abstract OrangePips Seeds { get; }
    public abstract OrangePeel Peel { get; }
}

public class NavelOrange : OrangeBase
{
    public override OrangePeel Peel { get { return new OrangePeel(); } }
    protected override OrangePips Seeds { get { return null; } }
}

public class ValenciaOrange : OrangeBase
{
    public override OrangePeel Peel { get { return new OrangePeel(); } }
    protected override OrangePips Seeds { get { return new OrangePips(6); } }
}

公平地说,如果我们有一个派生自 Ornament 类的 PlasticOrange,它只能实现 IOrange 而不能实现 Seeds 保护的方法.没事儿.根据定义,接口是调用者和对象之间的契约,而不是类与其子类之间的契约.抽象类与我们接近这个概念.这很好.您本质上提出的是语言中的另一种构造,通过它我们可以将子类从一个基类切换到另一个基类,而不会破坏构建.对我来说,这没有意义.

It is fair to argue that if we have a PlasticOrange that derives from a class Ornament, it can only implement IOrange and not the Seeds protected method. That is fine. An interface by definition is a contract between a caller and an object, not between a class and its subclasses. The abstract class is as close as we come to this concept. And that is fine. What you are essentially proposing is another construct in the language through which we can switch subclasses from one base class to another without breaking the build. To me, this doesn't make sense.

如果您要创建类的子类,则子类是基类的特化.它应该完全了解基类的任何受保护成员.但是如果你突然想把基类切换出去,那么子类应该与任何其他 IOrange 一起工作是没有意义的.

If you are creating a subclass of a class, the subclass is a specialization of the base class. It should be fully aware of any protected members of the base class. But if you suddenly want to switch the base class out, it makes no sense that the subclass should work with any other IOrange.

我想你有一个公平的问题,但它似乎是一个极端案例,老实说,我认为它没有任何好处.

I suppose you have a fair question, but it seems like a corner case and I don't see any benefit from it to be honest.

这篇关于为什么我不能拥有受保护的接口成员?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆