IT story

Java 인터페이스의 선택적 메소드

hot-time 2020. 8. 4. 22:52
반응형

Java 인터페이스의 선택적 메소드


Java에서 인터페이스를 구현하는 경우 내 이해에서 해당 인터페이스에 지정된 메소드는 해당 인터페이스를 구현하는 서브 클래스에서 사용해야합니다.

Collection 인터페이스와 같은 일부 인터페이스에는 선택 사항으로 주석 처리 된 메소드가 있지만 이것이 정확히 무엇을 의미합니까? 인터페이스에 지정된 모든 메소드가 필요하다고 생각함에 따라 조금 던져졌습니다.


여기에 대한 답변에 끔찍한 혼란이있는 것 같습니다.

Java 언어에서는 인터페이스의 모든 메소드가 해당 인터페이스의 모든 구현으로 구현되어야합니다. 기간. 이 규칙에는 예외가 없습니다. "컬렉션은 예외입니다"라고 말하는 것은 실제로 무슨 일이 일어나고 있는지에 대한 아주 모호한 이해를 암시합니다.

인터페이스에 맞는 두 가지 레벨의 레벨이 있음을 인식하는 것이 중요합니다.

  1. Java 언어로 확인할 수있는 것 이것은 꽤 많은 단지로 귀결이 어떤 방법 각각에 대한 구현은?

  2. 실제로 계약을 이행합니다. 즉, 구현시 인터페이스의 문서가 말한 것을 수행합니까?

    잘 작성된 인터페이스에는 구현에서 예상되는 것을 정확하게 설명하는 문서가 포함됩니다. 컴파일러가이를 확인할 수 없습니다. 문서를 읽고 그들이하는 말을해야합니다. 계약서에 명시된 내용을 수행하지 않으면 컴파일러 에 관한 한 인터페이스가 구현 되지만 결함 이 있거나 유효하지 않은 구현입니다.

Collections API를 디자인 할 때 Joshua Bloch는 다양한 컬렉션 변형 (예 : 읽기 가능, 쓰기 가능, 임의 액세스 등)을 구별하기 위해 매우 세분화 된 인터페이스를 사용하는 대신 주로 매우 거친 인터페이스 세트 만 갖기로 결정했습니다. Collection, List, Set그리고 Map다음 "선택"과 같은 특정 작업을 문서화합니다. 이는 세밀한 인터페이스로 인한 조합 폭발을 피하기위한 것입니다. 로부터 자바 컬렉션 API 디자인 자주 묻는 질문 :

문제를 상세하게 설명하기 위해 수정 가능성 개념을 계층에 추가한다고 가정합니다. ModifiableCollection, ModifiableSet, ModifiableList 및 ModifiableMap의 네 가지 새 인터페이스가 필요합니다. 이전에 단순한 계층 구조는 이제 지저분한 계층 구조입니다. 또한 제거 조작을 포함하지 않는 수정 불가능한 콜렉션과 함께 사용하려면 새로운 Iterator 인터페이스가 필요합니다. 이제 UnsupportedOperationException을 없앨 수 있습니까? 불행히도.

배열을 고려하십시오. 그것들은 대부분의 List 작업을 구현하지만 제거하고 추가하지는 않습니다. 그것들은 "고정 크기"목록입니다. 계층 구조에서이 개념을 캡처하려면 VariableSizeList 및 VariableSizeMap의 두 가지 새 인터페이스를 추가해야합니다. VariableSizeCollection 및 VariableSizeSet은 ModifiableCollection 및 ModifiableSet과 동일하기 때문에 추가 할 필요는 없지만 일관성을 위해 추가 할 수도 있습니다. 또한 추가 및 제거 작업을 지원하지 않는 수정 불가능한 List와 함께 사용할 수있는 새로운 다양한 ListIterator가 필요합니다. 이제 원래 4 개 대신 최대 10 개 또는 12 개의 인터페이스와 2 개의 새로운 Iterator 인터페이스가 있습니다. 다 했습니까? 아니.

로그 (예 : 오류 로그, 감사 로그 및 복구 가능한 데이터 개체에 대한 저널)를 고려하십시오. 이들은 제거 및 설정 (바꾸기)을 제외한 모든 List 작업을 지원하는 자연스러운 추가 전용 시퀀스입니다. 새로운 핵심 인터페이스와 새로운 반복자가 필요합니다.

수정 불가능한 컬렉션과 달리 불변 컬렉션은 어떻습니까? (즉, 고객이 변경할 수없고 다른 이유로 변경되지 않는 컬렉션). 많은 사람들이 이것이 동기화의 필요성없이 여러 스레드가 동시에 콜렉션에 액세스 할 수있게하므로 이것이 가장 중요한 차이점이라고 주장합니다. 이 지원을 유형 계층에 추가하려면 인터페이스가 4 개 더 필요합니다.

이제 우리는 최대 20 개 정도의 인터페이스와 5 개의 반복자를 가지고 있으며, 실제로는 어떤 인터페이스에도 깔끔하게 맞지 않는 컬렉션이 여전히있을 것입니다. 예를 들어 Map이 반환 한 컬렉션 뷰는 자연스러운 삭제 전용 컬렉션입니다. 또한 값을 기준으로 특정 요소를 거부하는 컬렉션이 있으므로 런타임 예외를 제거하지 않았습니다.

모든 것이 말되고 끝났을 때, 우리는 런타임 예외를 던질 수있는 매우 작은 핵심 인터페이스 세트를 제공함으로써 전체 문제를 회피하는 것이 건전한 엔지니어링 타협이라고 생각했습니다.

Collections API의 메소드가 "선택적 오퍼레이션"으로 문서화되었다고해서 구현에서 메소드 구현을 그대로 두거나 빈 메소드 본문을 사용할 수 있다는 의미는 아닙니다. 결과를 반환해야합니다). 오히려 유효한 구현 선택 (여전히 계약을 준수하는 선택)은을 던지는 것 UnsupportedOperationException입니다.

그 때문에 참고 UnsupportedOperationExceptionA는 RuntimeException당신이 멀리 컴파일러에 관한 한, 어떤 메소드 구현에서 던질 수 있습니다. 예를 들어의 구현에서 던질 수 있습니다 Collection.size(). 그러나, 문서화 Collection.size()가 이것이 허용된다고 말하지 않기 때문에 그러한 구현은 계약을 위반할 것 입니다.

따로 : Java의 Collections API에서 사용하는 접근 방식은 다소 논란의 여지가 있습니다 (그러나 처음 도입되었을 때보 다 지금은 아마 더 적습니다). 완벽한 세상에서 인터페이스 에는 옵션 작업 없으며 대신 세밀한 인터페이스가 사용됩니다. 문제는 자바가 유추 된 구조적 유형이나 교차 유형을 지원하지 않는다는 것입니다. 그래서 "올바른 방법"을 수행하려고 시도하면 콜렉션의 경우 매우 다루기 힘들어집니다.


인터페이스에 대한 구현 (비추 상) 클래스를 컴파일하려면 모든 메소드를 구현해야합니다.

그러나 구현이 단순한 예외 예외 인 '비 구현 된'( Collection인터페이스의 일부 메소드와 같은) 메소드를 생각하면 인터페이스 Collection는 일반적인 경우가 아니라 예외입니다. 일반적으로 클래스 구현은 모든 메소드를 구현해야합니다.

컬렉션의 "선택적"은 구현 클래스가 (위의 용어에 따라) 구현할 필요가 없으며 그냥 던질 것임을 의미 NotSupportedException합니다.

add()불변 컬렉션에 대한 좋은 예 -콘크리트는 단지 던지는 것 이외의 방법을 구현합니다.NotSupportedException

이 경우 Collection지저분한 상속 트리를 방지하기 위해 수행되므로 프로그래머가 비참하게 될 것입니다. 그러나 대부분의 경우이 패러다임은 권장되지 않으며 가능한 경우 피해야합니다.


최신 정보:

Java 8부터는 기본 메소드 가 도입되었습니다.

즉, 인터페이스는 구현을 포함하여 메소드를 정의 할 수 있습니다.
새로운 기능이 필요하지 않은 코드 조각에 대한 역 호환성을 계속 지원하면서 인터페이스에 기능을 추가 할 수 있도록 추가되었습니다.

이 메소드는 여전히 메소드를 선언하는 모든 클래스에 의해 구현되지만 인터페이스의 정의를 사용합니다.


Java의 인터페이스는 클래스 구현 계약을 선언합니다. 해당 인터페이스의 모든 메소드를 구현 해야 하지만 구현 클래스는 구현되지 않은 상태, 즉 공백으로 남겨 둘 수 있습니다. 고안된 예로서,

interface Foo {
  void doSomething();
  void doSomethingElse();
}

class MyClass implements Foo {
  public void doSomething() {
     /* All of my code goes here */
  }

  public void doSomethingElse() {
    // I leave this unimplemented
  }
}

이제 doSomethingElse()구현되지 않은 상태로 두어 하위 클래스가 구현할 수 있도록 남겨 두었습니다. 선택 사항입니다.

class SubClass extends MyClass {
    @Override
    public void doSomethingElse() {
      // Here's my implementation. 
    }
}

그러나 Collection 인터페이스에 대해 이야기하고 있다면 다른 사람들이 말했듯이 예외입니다. 특정 메소드가 구현되지 않은 상태에서 호출하면 UnsupportedOperationException예외 가 발생할 수 있습니다 .


Collection 인터페이스의 선택적 메소드는 메소드의 구현이 예외를 처리 할 수 ​​있지만 어쨌든 구현되어야 함을 의미합니다. 문서에 지정된대로 :

Some collection implementations have restrictions on the elements that they may contain. For example, some implementations prohibit null elements, and some have restrictions on the types of their elements. Attempting to add an ineligible element throws an unchecked exception, typically NullPointerException or ClassCastException. Attempting to query the presence of an ineligible element may throw an exception, or it may simply return false; some implementations will exhibit the former behavior and some will exhibit the latter. More generally, attempting an operation on an ineligible element whose completion would not result in the insertion of an ineligible element into the collection may throw an exception or it may succeed, at the option of the implementation. Such exceptions are marked as "optional" in the specification for this interface.


All methods have to be implemented for the code to compile, (aside from those with default implementations in Java 8+), but the implementation doesn't have to do anything functionally useful. Specifically, it:

  • May be blank (an empty method.)
  • May just throw an UnsupportedOperationException (or similar)

The latter approach is often taken in the collection classes - all the methods are still implemented, but some may throw an exception if called at runtime.


If we go through the code of AbstractCollection.java in grepCode which is a ancestor class for all collection implementations, it will help us to understand the meaning of optional methods. Here is the code for add(e) method in AbstractCollection class. add(e) method is optional according to collection interface

public boolean  add(E e) {

        throw new UnsupportedOperationException();
    } 

Optional method means it is already implemented in ancestor classes and it throws UnsupportedOperationException upon invocation. If we want to make our collection modifiable then we should override the optional methods in collection interface.


In fact, I am inspired by SurfaceView.Callback2 . I think this is the official way

public class Foo {
    public interface Callback {
        public void requiredMethod1();
        public void requiredMethod2();
    }

    public interface CallbackExtended extends Callback {
        public void optionalMethod1();
        public void optionalMethod2();
    }

    private Callback mCallback;
}

If your class doesnt need to implement optional methods, just "implements Callback". If your class need to implement optional methods, just "implements CallbackExtended".

Sorry for shit English.


Well, this topic has been adressed to ... yeah .. but think, one answer is missing. Im talking about the "Default Methods" of interfaces. For example, let's imagine you'll have a class for closing anything (like a destructor or something). Let's say it should have 3 methods. Let's call them "doFirst()", "doLast()" and "onClose()".

So we say we want any object of that type to at least realize "onClose()", but the other are optional.

You can realize that, using the "Default Methods" of interfaces. I know, this would most of the Time negate the reason of an interface, but if you are designing an framework, this can be useful.

So if you want to realize it this way, it would look the following

public interface Closer {
    default void doFirst() {
        System.out.print("first ... ");
    }
    void onClose();
    default void doLast() {
        System.out.println("and finally!");
    }
}

What now would happen, if you for example implemented it in an class called "Test", the compiler would be perfectly fine with the following:

public class TestCloser implements Closer {
    @Override
    public void onClose() {
        System.out.print("closing ... ");
    }
}

with the Output:

first ... closing ... and finally!

or

public class TestCloser implements Closer {
    @Override
    public void onClose() {
        System.out.print("closing ... ");
    }

    @Override
    public void doLast() {
        System.out.println("done!");
    }
}

with the output:

first ... closing ... done!

All combinations are possible. Anything with "default" can be implemented, but must not, however anything without must be implemented.

Hope it is not fully wrong that i now answer.

Have a great day everybody!

[edit1]: Please note: This only works in Java 8.


In Java 8 and later, the answer to this question is still valid but is now more nuanced.

First, these statements from the accepted answer remain correct:

  • interfaces are meant to specify their implicit behaviors in a contract (a statement of rules for behavior that implementing classes must obey in order to be considered valid)
  • there is a distinction between the contract (rules) and the implementation (programmatic coding of the rules)
  • methods specified in the interface MUST ALWAYS be implemented (at some point)

So, what is the nuance that is new in Java 8? When speaking of "Optional Methods" any of the following are now apt:

1. A method whose implementation is contractually optional

The "third statement" says that abstract interface methods must always be implemented and this remains true in Java 8+. However, as in the Java Collections Framework, it is possible to describe some abstract interface methods as "optional" in the contract.

In this case, the author who is implementing the interface can choose not to implement the method. The compiler will insist upon an implementation, however, and so the author uses this code for any optional methods that are not needed in the particular implementation class:

public SomeReturnType optionalInterfaceMethodA(...) {
    throw new UnsupportedOperationException();
}

In Java 7 and earlier, this was really the only kind of "optional method" that there was, i.e. a method that, if not implemented, threw an UnsupportedOperationException. This behavior is necessarily specified by the interface contract (eg. the optional interface methods of the Java Collections Framework).

2. A default method whose re-implementation is optional

Java 8 introduced the concept of default methods. These are methods whose implementation can be and is provided by the interface definition itself. It is generally only possible to provide default methods when the method body can be written using other interface methods (i.e., the "primitives"), and when this can mean "this object whose class has implemented this interface."

A default method must fulfill the contract of the interface (just like any other interface method implementation must). Therefore, specifying an implementation of the interface method in an implementing class is at the author's discretion (as long as the behavior is suitable to his or her purpose).

In this new environment, the Java Collections Framework could be rewritten as:

public interface List<E> {
    :
    :
    default public boolean add(E element) {
        throw new UnsupportedOperationException();
    }
    :
    :
}

In this way, the "optional" method add() has the default behavior of throwing an UnsupportedOperationException if the implementing class provides no new behavior of its own, which is exactly what you would want to have happen and which is compliant with the contract for List. If an author is writing a class that does not allow new elements to be added to a List implementation, the implementation of add() is optional because the default behavior is exactly what is needed.

In this case, the "third statement" above still holds true, because the method has been implemented in the interface itself.

3. A method that returns an Optional result

The final new kind of optional method is simply a method which returns an Optional. The Optional class provides a decidedly more object-oriented way of dealing with null results.

In a fluent style of programming, such as the kind commonly seen when coding with the new Java Streams API, a null result at any point causes the program to crash with a NullPointerException. The Optional class provides a mechanism for returning null results to client code in a way that enables the fluent style without causing client code to crash.


I was looking for a way to implement the call back interface, so implementing optional methods was necessary since I didn't want to implement every method for each call back.

So, instead of using an interface, I used a class with empty implementation such as:

public class MyCallBack{
    public void didResponseCameBack(String response){}
}

And you can set member variable CallBack like this,

c.setCallBack(new MyCallBack() {
    public void didResponseCameBack(String response) {
        //your implementation here
    }
});

then call it like this.

if(mMyCallBack != null) {
    mMyCallBack.didResponseCameBack(response);
}

This way, you wouldn't need to worry about implementing every methods per call back, but only override the ones you need.


Although it does not answer the OP's question, it is worth noting that as of Java 8 adding default methods to interfaces is in fact doable. The default keyword placed in an interface's method signature will result in a class having the option to override the method, but not require it to.


Oracle's Java Collections Tutorial:

To keep the number of core collection interfaces manageable, the Java platform doesn't provide separate interfaces for each variant of each collection type. (Such variants might include immutable, fixed-size, and append-only.) Instead, the modification operations in each interface are designated optional — a given implementation may elect not to support all operations. If an unsupported operation is invoked, a collection throws an UnsupportedOperationException. Implementations are responsible for documenting which of the optional operations they support. All of the Java platform's general-purpose implementations support all of the optional operations.

참고URL : https://stackoverflow.com/questions/10572643/optional-methods-in-java-interface

반응형