program tip

Java가 인터페이스에서 개인 멤버를 허용하지 않는 이유는 무엇입니까?

radiobox 2020. 10. 16. 07:18
반응형

Java가 인터페이스에서 개인 멤버를 허용하지 않는 이유는 무엇입니까?


Java가 인터페이스에서 개인 멤버를 허용하지 않는 이유는 무엇입니까? 특별한 이유가 있습니까?


로부터 Java 언어 사양 (액세스 제어) :

"Java 프로그래밍 언어는 액세스 제어를위한 메커니즘을 제공하여 패키지 또는 클래스의 사용자가 해당 패키지 또는 클래스 구현의 불필요한 세부 사항에 의존하지 않도록 방지합니다."

액세스 제어는 구현 세부 정보를 숨기는 것입니다. 인터페이스에는 숨길 구현이 없습니다.


Java 9에서는 인터페이스의 개인 메서드가 가능합니다.

Java 9 사양

javac 컴파일러 팀은 JDK의 9 b54 빌드로 시작하는 인터페이스의 private 메서드에 대한 컴파일러 지원을 발표하게되어 기쁩니다.


개인 인터페이스 메소드는 JEP-213의 일부인 Java 9의 일부입니다 . Java 8의 인터페이스는 기본 메소드를 가질 수 있으므로 비공개 메소드는 여러 기본 메소드가 공유 비공개 메소드를 사용하도록 허용합니다.


Java 8부터 인터페이스는 기본 메소드를 가질 수 있으며 Java 9부터 인터페이스는 동일한 인터페이스에서 기본 메소드로만 액세스 할 수있는 개인 메소드를 가질 수 있습니다.


인터페이스는 인터페이스를 구현하는 모든 클래스에서 제공하는 API를 설명하는 데 사용됩니다. 정의의 인터페이스에는 상태가 없기 때문에 필드 멤버를 선언 할 필요가 없습니다.


그러한 인터페이스를 구현할 방법이 없습니다. 내가 제시 한 질문에 대한 답변 은 비공개 메소드로 인터페이스를 구현하는 것이 불가능하다는 것을 강력하게 제안합니다 (규칙을 근본적으로 변경하지 않고서는). 이것은 보호 및 패키지 비공개 메소드가 허용되지 않는 이유에 대한 질문을 남깁니다.

class OuterClass
{
     void run ( MyInterface x )
     {
           x . publicMethod ( ) ;  // why not?
           x . protectedMethod ( ) ; // why not?
           x . packagePrivateMethod ( ) ; // why not?
           x . privateMethod ( ) ; // why not?
     }

     interface MyInterface
     {
           public abstract void publicMethod ( ) ; // OK

           protected abstract void protectedMethod ( ) ; // why not?

           abstract void packagePrivateMethod ( ) ; // in interface default is public, but why not package private

           private void privateMethod ( ) ; // impossible to implement
     }

     class MyImpl implements MyInterface
     {
           public void publicMethod ( ) { } // ok

           protected void protectedMethod ( ) { } // no sweat

           void packagePrivateMethod ( ) { } // no sweat

           private void privateMethod ( ) { } // not happening
     }
}

아래 코드는 원하는 결과를 얻을 수 있습니다. 모든 방법이 공용이지만 공용 방법 만 사실상 공용입니다. 보호 된 방법은 효과적으로 보호됩니다. packagePrivateMethod는 효과적으로 packagePrivate입니다. privateMethod는 사실상 비공개입니다.

class WorkAround
{
     void run ( MyPrivateInterface x )
     {
           x . publicMethod ( ) ;  
           x . protectedMethod ( ) ; 
           x . packagePrivateMethod ( ) ; 
           x . privateMethod ( ) ; 
     }

     public interface MyPublicInterface { void publicMethod ( ) ; }

     protected interface MyProtectedInterface extends MyPublicInterface { void protectedMethod ( ) ; }

     interface MyPackagePrivateInterface extends MyProtectedInterface { void packagePrivateMethod ( ) ; }

     private interface MyPrivateInterface extends MyPackagePrivateInterface { void privateMethod ( ) ; }
}

According to the Java programming language scope of the private members is limited to the class in which it is declared and can be accessed only by methods of that class. But inteface doesn't have a method body hence there is no use of declaring private members inside an interface.


It is because they would be useless.

There would be no way to call a private method.

Private members are an implementation detail. An interface is about the public role that a class can take on.


Java allows private methods in an interface in Java 9. The default methods were introduced in Java 8. It is possible that multiple default methods want to share some code, then this code can be moved to a private method without exposing it to outer world. This bug has been fixed and starting in JDK 9 build 54, compiler support for private interface methods have been resurrected.

public interface IData{
   default void processData(int data) {
      validate(data);
      // do some work with it
   }
   default void consumeData(int data) {
      validate(data);
      // do some work with it
   }
   private void validate(int data) {
     // validate data
   }
}

private fields would not be completely useless as other fields and inner classes could access them.

However private methods could not be implemented, even in nested classes, making them almost useless. You could read them using reflection, but that is rather an edge case.


Private members don't make sense in interface. Interface is a way to access a class with defined methods where you don't need to see the inners of that class.

Private members disagree to that.


Members of a class that are declared private are not inherited by subclasses of that class. Only members of a class that are declared protected or public are inherited by subclasses declared in a package other than the one in which the class is declared.

Source

So you don't have any working methods in an interface which can work with that private non-inheritable field, Then why should it exist?


Yep, can't do that. For all those commenting on why it shouldn't:

Imagine I have Class A, which utilizes interface I. Class B, extends Class A, therefore also inheriting all interface methods in A.

Now, imagine I want a private method in Class A, but want it contractually defined for other classes as well (Maybe a class C, which doesn't necessarily extend Class B or A).

Perhaps for an "initialization" method, that I want for all classes using an I interface. But obviously I don't want an initialization method to be public.... since it should only be used once, or as the class deems necessary, not just because you want to use it all willy-nilly.

The only solution is a workaround, or by simply forcing the init method into the classes themselves without an interface.

I understand the reason not too, for sure, but still, it can come in handy sometimes. Clearly Oracle agrees as they're allowing private interface methods in JDK 9.

What I did, for mine anyway, was place a simple boolean variable, that way the interface method (which should be private) can be flagged as true (initialized = true) after being set once. Then when called again the method simply does nothing. This way the interface method can be implemented as public, but since the constructor (of my class) calls the method first, this sets the variable to true, and so it can't be called again.

Otherwise you'd have to try a different workaround if you only want the inner workings of the class to use it.... perhaps a method itself sets a flag on and off as it uses it. When the flag is false, the method does nothing (this would be when someone calls it from outside the class). However, when the classes own methods call it, they quickly set the flag to true, then call the method, then set the flag to false??

In the end kind of mute. Probably just better for now to simply place the private class into the class itself and cut-out the interface altogether.

참고URL : https://stackoverflow.com/questions/10169654/why-doesnt-java-allow-private-members-in-interface

반응형