programing

인터페이스의 컨스트럭터?

copyandpastes 2022. 7. 2. 21:27
반응형

인터페이스의 컨스트럭터?

인터페이스에서는 컨스트럭터를 정의할 수 없다는 것을 알고 있습니다.하지만 왜 그런지 궁금해요. 아주 유용할 것 같아서요.

따라서 클래스의 일부 필드가 이 인터페이스의 모든 구현에 대해 정의되어 있는지 확인할 수 있습니다.

예를 들어 다음 메시지클래스를 생각해 보겠습니다.

public class MyMessage {

   public MyMessage(String receiver) {
      this.receiver = receiver;
   }

   private String receiver;

   public void send() {
      //some implementation for sending the mssage to the receiver
   }
}

이 클래스의 인터페이스를 정의하여 메시지인터페이스를 실장하는 클래스를 늘릴 수 있는 경우, 정의할 수 있는 것은 송신 메서드뿐이며 컨스트럭터는 없습니다.그러면 이 클래스의 모든 구현에 실제로 수신기 세트가 있는지 어떻게 확인할 수 있을까요?if like like like like 의 방법을 할 수 있습니다.setReceiver(String receiver)나는 이 방법이 정말 불리하다고 확신할 수 없다.이치노

설명한 내용 중 몇 가지를 예로 들어 보겠습니다.

"따라서 클래스의 일부 필드가 이 인터페이스의 모든 구현에 대해 정의되어 있는지 확인할 수 있습니다.

"에서 메시지 인터페이스를 구현하는 클래스를 더 많이 가질 수 있도록 이 클래스의 인터페이스를 정의하면 전송 메서드만 정의할 수 있고 생성자는 정의할 수 없습니다."

...이러한 요건이 바로 추상적인 수업의 목적입니다.

인터페이스에서 컨스트럭터를 허용하면 발생하는 문제는 여러 인터페이스를 동시에 구현할 수 있다는 점에서 발생합니다.클래스가 서로 다른 컨스트럭터를 정의하는 여러 인터페이스를 구현할 경우 클래스는 여러 컨스트럭터를 구현해야 하며 각 컨스트럭터는 하나의 인터페이스만 충족하고 다른 인터페이스는 지원하지 않습니다.이러한 각 생성자를 호출하는 개체를 생성할 수 없습니다.

또는 코드:

interface Named { Named(String name); }
interface HasList { HasList(List list); }

class A implements Named, HasList {

  /** implements Named constructor.
   * This constructor should not be used from outside, 
   * because List parameter is missing
   */
  public A(String name)  { 
    ...
  }

  /** implements HasList constructor.
   * This constructor should not be used from outside, 
   * because String parameter is missing
   */
  public A(List list) {
    ...
  }

  /** This is the constructor that we would actually 
   * need to satisfy both interfaces at the same time
   */ 
  public A(String name, List list) {
    this(name);
    // the next line is illegal; you can only call one other super constructor
    this(list); 
  }
}

인터페이스는 API에 대한 계약을 정의합니다.이것은 API의 구현자와 사용자 모두가 동의하는 일련의 메서드입니다.인터페이스에는 인스턴스 구현이 없기 때문에 컨스트럭터가 없습니다.

설명하는 사용 사례는 생성자가 하위 클래스에 구현된 추상 메서드의 메서드를 호출하는 추상 클래스와 유사합니다.

여기서 본질적인 문제는 기본 생성자가 실행되는 동안 하위 개체가 아직 생성되지 않았기 때문에 예측할 수 없는 상태에 있다는 것입니다.

요약: 부모 컨스트럭터에서 오버로드된 메서드를 호출할 때 mindprod를 인용할 때 문제가 발생하는지 확인합니다.

일반적으로 컨스트럭터에서 최종적이지 않은 메서드를 호출하지 않도록 해야 합니다.문제는 파생 클래스의 인스턴스 이니셜라이저/변수 초기화가 기본 클래스의 생성자 다음에 수행된다는 것이다.

해 볼 수 은 '어느 정도'를 입니다.getInstance()method를 사용하여 구현자가 처리해야 할 파라미터를 인식할 수 있도록 합니다.추상적인 클래스만큼 견고하지는 않지만 인터페이스로서의 유연성은 향상됩니다.

, 이 에서는, 「」, 「」를 사용할 필요가 있습니다.getInstance()이 인터페이스의 모든 오브젝트를 인스턴스화합니다.

예.

public interface Module {
    Module getInstance(Receiver receiver);
}

인터페이스에는 서브클래스의 오브젝트 작성 중에 초기화할 필요가 없는 스태틱필드만 있습니다인터페이스 메서드는 서브클래스에 실제 실장을 제공해야 합니다.따라서 인터페이스에 컨스트럭터가 필요 없습니다.

두 번째 이유 - 서브클래스의 오브젝트 작성 중에 부모 컨스트럭터를 호출합니다.그러나 둘 이상의 인터페이스가 구현될 경우 인터페이스 컨스트럭터 호출 중에 어떤 인터페이스 컨스트럭터가 먼저 호출할지에 대한 충돌이 발생합니다.

인터페이스의 모든 구현에 특정 필드가 포함되도록 하려면 해당 필드의 getter를 인터페이스에 추가해야 합니다.

interface IMyMessage(){
    @NonNull String getReceiver();
}
  • 캡슐화가 깨지지 않습니다.
  • 에게 이 것입니다.Receiver오브젝트는 (컨스트럭터 또는 설정자에 의해) 어떤 방식으로든 클래스에 전달되어야 합니다.

인터페이스 메서드에서 참조되지 않는 의존관계는 인터페이스가 강제하는 것이 아니라 구현 세부사항으로 간주해야 합니다.물론 예외가 있을 수 있지만, 원칙적으로 인터페이스를 예상되는 동작으로 정의해야 합니다.특정 실장의 내부 상태가 인터페이스의 설계상의 문제가 되어서는 안 됩니다.

이는 인터페이스에서는 메서드 본문을 정의할 수 없기 때문입니다.단, 정의하는 모든 메서드에 대해 인터페이스가 기본적으로 가지는 추상 수식자와 같은 클래스에 컨스트럭터를 정의해야 합니다.그렇기 때문에 인터페이스에서 컨스트럭터를 정의할 수 없습니다.

이유에 대해서는, 이 질문을 참조해 주세요(댓글에서 인용).

이러한 작업을 꼭 수행해야 하는 경우에는 인터페이스가 아닌 추상적인 기본 클래스가 필요할 수 있습니다.

다음은 이 테크니컬을 사용하는 예를 다음에 나타냅니다.이 특정 예제에서는 코드가 모크를 사용하여 Firebase에 호출하고 있습니다.MyCompletionListener추상 클래스로 마스크된 인터페이스, 컨스트럭터와의 인터페이스입니다.

private interface Listener {
    void onComplete(databaseError, databaseReference);
}

public abstract class MyCompletionListener implements Listener{
    String id;
    String name;
    public MyCompletionListener(String id, String name) {
        this.id = id;
        this.name = name;
    }
}

private void removeUserPresenceOnCurrentItem() {
    mFirebase.removeValue(child("some_key"), new MyCompletionListener(UUID.randomUUID().toString(), "removeUserPresenceOnCurrentItem") {
        @Override
        public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {

        }
    });
    }
}

@Override
public void removeValue(DatabaseReference ref, final MyCompletionListener var1) {
    CompletionListener cListener = new CompletionListener() {
                @Override
                public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {
                    if (var1 != null){
                        System.out.println("Im back and my id is: " var1.is + " and my name is: " var1.name);
                        var1.onComplete(databaseError, databaseReference);
                    }
                }
            };
    ref.removeValue(cListener);
}

일반적으로 컨스트럭터는 오브젝트에 관해 특정 클래스의 비정적 멤버를 초기화하기 위한 것입니다.

선언된 메서드만 있고 정의된 메서드는 없기 때문에 인터페이스에 대한 오브젝트는 생성되지 않습니다.선언된 메서드에 오브젝트를 작성할 수 없는 이유는 오브젝트 작성은 (히프 메모리의) 비스타틱멤버에게 메모리를 할당하는 것에 불과합니다.

JVM은 완전히 개발되어 즉시 사용할 수 있는 멤버용 메모리를 만듭니다.이러한 멤버를 기반으로 JVM은 멤버에 필요한 메모리 양을 계산하여 메모리를 만듭니다.

선언된 메서드의 경우, JVM은 선언된 메서드에 필요한 메모리 양을 계산할 수 없습니다.이러한 메서드는 이 시점까지 구현되지 않을 것이기 때문입니다.인터페이스에서는 오브젝트를 작성할 수 없습니다.

결론:

오브젝트를 생성하지 않으면 컨스트럭터를 통해 비정적 멤버를 초기화할 수 없습니다.그렇기 때문에 컨스트럭터는 인터페이스 내에서 사용할 수 없습니다.(인터페이스 내에서는 컨스트럭터를 사용할 수 없기 때문에)

언급URL : https://stackoverflow.com/questions/2804041/constructor-in-an-interface

반응형