program story

보호 된 인터페이스 멤버를 가질 수없는 이유는 무엇입니까?

inputbox 2020. 11. 14. 10:11
반응형

보호 된 인터페이스 멤버를 가질 수없는 이유는 무엇입니까?


인터페이스에서 보호 액세스 멤버를 선언하는 것에 대한 주장은 무엇입니까? 예를 들어 이것은 유효하지 않습니다.

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

이 예제에서 인터페이스 IOrange는 구현 자가 최소한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인터페이스 멤버 의 의도는 상속자 (하위 클래스)에 대한 지원 계약을 제공하는 것 입니다. 예를 들면 다음과 같습니다.

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

(분명히 이것은 structs 에서는 작동하지 않습니다 )

인터페이스에서 private또는 internal수정 자에 대한 사례를 많이 볼 수는 없지만 publicprotected수정자를 모두 지원하는 것은 완벽하게 합리적으로 보입니다.


s 에서 protected멤버를 완전히 interface분리하여 s 에서 멤버 의 유용성을 설명하려고합니다 interface.

support상속자 계약을 적용 하기 위해 새로운 C # 키워드를 상상해 보겠습니다. 그러면 다음과 같이 선언합니다.

public support IOrangeSupport
{
    OrangePips Seeds { get; }
}

이를 통해 상속자에게 보호 된 멤버를 제공하는 클래스를 계약 할 수 있습니다.

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

편집 : Ornament 클래스에서 파생 된 PlasticOrange가 있다면 IOrange 만 구현할 수 있고 Seeds 보호 메서드는 구현할 수 없다고 주장하는 것이 타당합니다. 괜찮습니다. 정의에 의한 인터페이스는 클래스와 하위 클래스 사이가 아니라 호출자와 객체 사이의 계약입니다. 추상 클래스는 우리가이 개념에 도달 한만큼 가깝습니다. 그리고 괜찮습니다. 기본적으로 제안하는 것은 빌드를 중단하지 않고 한 기본 클래스에서 다른 기본 클래스로 하위 클래스를 전환 할 수있는 언어의 또 다른 구조입니다. 나에게 이것은 말이되지 않는다.

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.


Can't see why would one want this. If you want derived class to provide an implementation of a particular method, go for abstract base classes. Interfaces are just that - interfaces. A public contract, nothing else. Think of interface as of specification which describes how should the implementation look to the outside world. A specification for a two-pin plug does not state (at least I assume that) what it's internal structure should be like. It just must be interface-compatible with a plug socket. Plug
(source: made-in-china.com)


Because it makes no sense. An interface is a publicly exposed contract. I am an IThing, therefore I will perform IThing methods if asked. You can't ask an IThing to confirm it performs methods it can't tell you about.


Interfaces exist to allow people to access your class without knowing what the concrete implementation is. It completely divorices the implementation from the data passing contract.

Therefore, everything in an interface must be public. Non-public members are only useful if you have access to the implementation and therefore don't meaningfully contribute to an interface definition.


Interface members are a public API; things like protected etc are implementation details - and interfaces don't have any implementation. I suspect what you are looking for is explicit interface implementation:

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

An interface is a contract that promises certain functionality to clients. In other words, the purpose of an interface is to be able to cast a type into it and pass it around like that to code that needs the features guaranteed by that interface. Since client code of a type cannot access protected members of that type, it makes no sense to declare protected items in an interface.


An interface is just like the shape of a key.

enter image description here

It's not the key.

It's not the lock.

It's just the slim contact point.

For this reason all the members of the interface (that defines the shape of the key) must be public.

For a key to open a lock it is important that they both share the same shape.

By making the shape (the interface) public, you can let others create compatible locks or compatible keys.

Otherwise, making it (the interface) internal you will not allow others to create compatible locks or compatible keys.


An interface is all about what a certain object can do, so when using a class which implements that interface the developer will expect all the members to be implemented, so the protected access modifier won't mean anything for interfaces.


There's sound judgment in current design of interfaces which is that it offers implementers greater flexibility. Remember that very often interfaces are written by framework programmers and implementers are different folks. To enforce implementation would be needlessly harsh.


By implementing an interface the type states that it supports a specific set of methods. If any of these methods were not public, it would not be available to callers and thus the type would not support the interface as stated.


An Interface contains only public members. Protected means whatever you're declaring is only available to the class and derived class instances.


Any class which implements a .net interface will have to include implementations of all of the interface members. Further, any class can expose to a derived class whatever members it wishes. Requiring that an implementation of an interface must include a member which will only be usable from derived classes would serve no useful purpose, unless either (1) such a member could be visible to something outside the interface, or (2) interface implementations could use members which they did not themselves define. If interfaces were allowed to include nested classes (which could access the interfaces' protected members), then protected interface members would make sense. Indeed, they could be very useful if a class nested within an interface could define extension methods for that interface. Unfortunately, no such facility exists.

BTW, even without being able to nest classes in interfaces, it would still be useful to apply an internal access modifier to interface members, with the effect that only the assembly where the interface is defined would be able to define any implementations for it.

참고URL : https://stackoverflow.com/questions/516148/why-cant-i-have-protected-interface-members

반응형