为什么我不能拥有受保护的接口成员?

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

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

在这个例子中, IOrange接口将保证实现者至less向其inheritance者提供一个OrangePips实例。 如果实施者想要的话,他们可以将范围扩大到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成员在接口上的意图是为inheritance者 (子类)提供支持合同,例如:

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

(无可否认,这不适用于struct s)

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


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

让我们设想一个新的C#关键字, support ,强制inheritance者合同,以便我们声明如下:

 public support IOrangeSupport { OrangePips Seeds { get; } } 

这将允许我们合同类提供受保护的成员给他们的inheritance人:

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

这并不是特别有用,因为类首先提供protected成员就意味着这个合同。

但是,我们也可以这样做:

 public interface IOrange : IOrangeSupport { ... } 

从而将IOrangeSupport应用于实现IOrange所有类,并要求它们提供特定的protected成员 – 这是我们目前不能做的事情。

我认为每个人都只是公开的接口,没有实现的细节。 你在找什么是抽象类 。

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

编辑:这是公平的,争辩​​说,如果我们有一个从类装饰派生的PlasticOrange,它只能实现IOrange,而不是种子保护的方法。 没事儿。 根据定义,接口是调用者和对象之间的契约,而不是在类和它的子类之间。 抽象类和我们这个概念一样接近。 这很好。 你基本上提出的是另一种语言构造,通过它我们可以在不破坏构build的情况下将子类从一个基类切换到另一个基类。 对我来说,这是没有意义的。

如果你正在创build一个类的子类,那么这个子类是基类的一个专门化。 它应该完全知道基类的任何受保护的成员。 但是,如果你突然想要切换基类,那么子类应该与任何其他IOrange一起工作是没有意义的。

我想你有一个公平的问题,但似乎是一个angular落的情况下,我不认为这是诚实的任何好处。

不明白为什么要这样做。 如果您希望派生类提供特定方法的实现,请参阅抽象基类。 接口就是这样 – 接口。 公共契约,没有别的。 将接口视为规范,描述了实现对外部世界应如何看待。 一个双引脚插头的规范没有说明(至less我假设)它的内部结构应该是什么样的。 它只是必须与sockets兼容。 插头http://www.made-in-china.com/image/2f0j00MCetlafAYTWcM/Two-Round-pin-Plug-with-Power-Wire.jpg

因为这是没有意义的。 一个接口是一个公开的合同。 我是一个IThing,因此如果询问我将执行IThing方法。 你不能要求IThing来确认它执行它不能告诉你的方法。

接口成员一个公共API; 像protected东西等是实现细节 – 接口没有任何实现。 我怀疑你正在寻找的是明确的接口实现:

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

接口的存在允许人们在不知道具体实现是什么的情况下访问你的类。 它完全与数据传递契约的执行有分歧。

因此,界面中的所有内容都必须公开。 非公开成员只有在有权访问实现的情况下才有用,因此不会对接口定义做出有意义的贡献。

接口是向客户承诺特定function的合同。 换句话说,接口的目的是能够将types转换为types,并将其传递到需要该接口保证的特性的代码。 由于types的客户端代码无法访问该types的受保护成员,因此在接口中声明受保护的项目是没有意义的。

界面就像一个键的形状

在这里输入图像说明

这不是关键。

这不是锁。

这只是苗条的接触点。 (简单!)

出于这个原因,界面的所有成员(定义键的形状)必须是公开的。

对于打开锁的钥匙来说,重要的是它们都具有相同的形状。

通过公开形状(界面),可以让其他人创build兼容的锁或兼容的键。

否则,使它(接口)在内部不允许其他人创build兼容的锁或兼容的密钥。

一个接口是关于某个对象可以做什么的,所以当使用实现这个接口的类时,开发人员会期望所有成员都被实现,所以受保护的访问修饰符对于接口来说并不意味着什么。

在目前的接口devise中有很好的判断力,它为实现者提供了更大的灵活性。 请记住,接口通常是由框架程序员编写的,实现者是不同的人。 强制执行将是不必要的苛刻。

通过实现一个接口,types声明它支持一组特定的方法。 如果这些方法中的任何一个都不公开,那么调用者将无法使用这些方法,因此types将不支持所述的接口。

一个接口只包含公共成员。 受保护的手段无论你声明只适用于类和派生类实例。

任何实现.net接口的类都必须包含所有接口成员的实现。 此外,任何类都可以暴露给派生类,无论它希望如何。 要求一个接口的实现必须包含一个只能从派生类中使用的成员,除非(1)这样一个成员对接口外部的东西可见,或者(2)接口实现可以使用他们没有自己定义的成员。 如果接口允许包含嵌套类(可以访问接口的protected成员),那么protected接口成员将是合理的。 事实上,如果嵌套在接口中的类可以定义该接口的扩展方法,那么它们可能非常有用。 不幸的是,这样的设施不存在。

顺便说一句,即使不能在接口中嵌套类,将internal访问修饰符应用于接口成员仍然有用,其效果是只有定义了接口的程序集才能够为其定义任何实现。