Interface implements overriding its own methods to create an object of itself as DEFAULT

白昼怎懂夜的黑 提交于 2020-02-04 20:46:09

问题


I've read many threads with questions which looks like questions I am going to ask. However, I can not find satisfactory answers which could be applied to my questions, since there are more than one fold in my questions, seperated in three aspects.

This is the interface SubtitleDecoderFactory in https://github.com/google/ExoPlayer/blob/release-v2/library/core/src/main/java/com/google/android/exoplayer2/text/SubtitleDecoderFactory.java

As I understand, an interace is abstraction and can not have concrete implementation of methods (maybe new java allows this, but since I am new to java, let's stick with the genaral rules of Java). So It makes sense to me that there are two absract mothod declarations in the interface, which are "boolean supportsFormat(Format format)" and "SubtitleDecoder createDecoder(Format format)". But what I don't understand and my questions are:

  1. Why can this interface implements "SubtitleDecoderFactory DEFAULT = new SubtitleDecoderFactory()", which looks like an implementation of initializing method?

  2. This interface initializes itself by overriding its own methods, is it an meaningless action? (an interface is meant to have other classes to implement it, not itself, am I correct?)

  3. What are the benifits of creating an object of itself in an interface, assuming questions 1 and 2 are valid?

  4. Is it that an instance of a class which implements this interface will have the instance of DEFAULT of this intetface?


public interface SubtitleDecoderFactory {


  boolean supportsFormat(Format format);


  SubtitleDecoder createDecoder(Format format);


  SubtitleDecoderFactory DEFAULT =
      new SubtitleDecoderFactory() {

        @Override
        public boolean supportsFormat(Format format) {
          @Nullable String mimeType = format.sampleMimeType;
          return MimeTypes.TEXT_VTT.equals(mimeType)
              || MimeTypes.TEXT_SSA.equals(mimeType)
              || MimeTypes.APPLICATION_TTML.equals(mimeType)
              || MimeTypes.APPLICATION_MP4VTT.equals(mimeType)
              || MimeTypes.APPLICATION_SUBRIP.equals(mimeType)
              || MimeTypes.APPLICATION_TX3G.equals(mimeType)
              || MimeTypes.APPLICATION_CEA608.equals(mimeType)
              || MimeTypes.APPLICATION_MP4CEA608.equals(mimeType)
              || MimeTypes.APPLICATION_CEA708.equals(mimeType)
              || MimeTypes.APPLICATION_DVBSUBS.equals(mimeType)
              || MimeTypes.APPLICATION_PGS.equals(mimeType);
        }

        @Override
        public SubtitleDecoder createDecoder(Format format) {
          @Nullable String mimeType = format.sampleMimeType;
          if (mimeType != null) {
            switch (mimeType) {
              case MimeTypes.TEXT_VTT:
                return new WebvttDecoder();
              case MimeTypes.TEXT_SSA:
                return new SsaDecoder(format.initializationData);
              case MimeTypes.APPLICATION_MP4VTT:
                return new Mp4WebvttDecoder();
              case MimeTypes.APPLICATION_TTML:
                return new TtmlDecoder();
              case MimeTypes.APPLICATION_SUBRIP:
                return new SubripDecoder();
              case MimeTypes.APPLICATION_TX3G:
                return new Tx3gDecoder(format.initializationData);
              case MimeTypes.APPLICATION_CEA608:
              case MimeTypes.APPLICATION_MP4CEA608:
                return new Cea608Decoder(mimeType, format.accessibilityChannel);
              case MimeTypes.APPLICATION_CEA708:
                return new Cea708Decoder(format.accessibilityChannel, format.initializationData);
              case MimeTypes.APPLICATION_DVBSUBS:
                return new DvbDecoder(format.initializationData);
              case MimeTypes.APPLICATION_PGS:
                return new PgsDecoder();
              default:
                break;
            }
          }
          throw new IllegalArgumentException(
              "Attempted to create decoder for unsupported MIME type: " + mimeType);
        }
      };
}

回答1:


  1. Why can this interface implements "SubtitleDecoderFactory DEFAULT = new SubtitleDecoderFactory()", which looks like an implementation of initializing method?

The interface is not implementing anything. What you have is a public, static, final field named DEFAULT which is assigned an instance of SubtitleDecoderFactory.


  1. This interface initializes itself by overriding its own methods, is it an meaningless action? (an interface is meant to have other classes to implement it, not itself, am I correct?)

Again, the interface is not "initializing itself" nor implementing itself. What you have is an example of an anonymous class. It is this anonymous class which is implementing SubtitleDecoderFactory. The anonymous class is instantiated and the instance is assigned to the DEFAULT field; this happens when the Class is initialized.


  1. What are the benifits of creating an object of itself in an interface, assuming questions 1 and 2 are valid?

In this case, a default implementation of SubtitleDecoderFactory is being provided. There's also only ever a single instance of this default implementation, since all fields declared in an interface are implicitly public, static, and final; this is an example of a singleton.

One possible advantage here is you don't have to declare another named class. And since the goal is apparently to have a singleton, there's no need for a named class either.


  1. Is it that an instance of a class which implements this interface will have the instance of DEFAULT of this intetface [sic]?

Remember that DEFAULT is a field which references an instance of an anonymous class. Will all implementations of SubtitleDecoderFactory have access to this field? Yes, but not specifically because they are implementing the interface.

Since all fields declared in an interface are public, static, and final the DEFAULT field is a constant (though not a compile-time constant). Static fields are associated with the class instead of instances of that class. In other words, any class which can "see" SubtitleDecoderFactory has access to the DEFAULT field. For example:

/* import SubtitleDecoderFactory interface as needed */

public class Main {

  public static void main(String[] args) {
    System.out.println(SubtitleDecoderFactory.DEFAULT == SubtitleDecoderFactory.DEFAULT);
  }

}



回答2:


new SubtitleDecoderFactory() { ... } creates an instance of an anonymous inner class that implements the interface SubtitleDecoderFactory. This instance is then assigned to the static field DEFAULT ("Every field declaration in the body of an interface is implicitly public, static, and final", JLS, §9.3).

In the rest of the program, the instance of the anonymous class is accessible through SubtitleDecoderFactory.DEFAULT.



来源:https://stackoverflow.com/questions/59494282/interface-implements-overriding-its-own-methods-to-create-an-object-of-itself-as

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!