接口实现了自己的方法,以创建自己的对象为DEFAULT

时间:2019-12-26 23:01:06

标签: java object interface overriding new-operator

我已经阅读了许多有关问题的主题,这些问题看起来像我要问的问题。但是,我找不到可以用于我的问题的令人满意的答案,因为我的问题有很多折,分为三个方面。

这是https://github.com/google/ExoPlayer/blob/release-v2/library/core/src/main/java/com/google/android/exoplayer2/text/SubtitleDecoderFactory.java中的SubtitleDecoderFactory接口

据我了解,接口是抽象的,不能具体实现方法(也许新的Java允许这样做,但是由于我是Java新手,所以请坚持使用Java的一般规则)。因此,对我来说有意义的是,接口中有两个抽象方法声明,分别是“布尔值supportsFormat(格式格式)”和“ SubtitleDecoder createDecoder(格式格式)”。但是我不明白,我的问题是:

  1. 为什么此接口可以实现“ SubtitleDecoderFactory DEFAULT = new SubtitleDecoderFactory()”,它看起来像是初始化方法的实现?

  2. 此接口通过重写其自己的方法进行初始化,这是没有意义的操作吗? (接口是要有其他类来实现它,而不是本身,是吗?)

  3. 假设问题1和2有效,在接口中创建自身对象的好处是什么?

  4. 是实现该接口的类的实例是否具有该界面的DEFAULT实例?


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

2 个答案:

答案 0 :(得分:3)

new SubtitleDecoderFactory() { ... }创建一个实现接口SubtitleDecoderFactory的{​​{3}}的实例。然后,将此实例分配给静态字段DEFAULT(“ 接口主体中的每个字段声明都是隐式publicstaticfinal ”,anonymous inner class)。

在程序的其余部分,可通过SubtitleDecoderFactory.DEFAULT访问匿名类的实例。

答案 1 :(得分:1)

  
      
  1. 为什么此接口可以实现“ SubtitleDecoderFactory DEFAULT = new SubtitleDecoderFactory()”,它看起来像是初始化方法的实现?
  2.   

该接口未执行任何操作。您拥有的是名为public的{​​{1}},staticfinal 字段,并为其分配了DEFAULT的实例。


  
      
  1. 此接口通过覆盖其自身的方法进行初始化,这是没有意义的动作吗? (接口是要有其他类来实现它,而不是本身,是吗?)
  2.   

同样,该接口既不是“初始化自身”也不是实现自身。您所拥有的是一个匿名类的示例。这个匿名类正在实现SubtitleDecoderFactory。匿名类被实例化,并且实例被分配到SubtitleDecoderFactory字段; DEFAULT初始化时会发生这种情况。


  
      
  1. 假设问题1和2有效,在接口中创建自身对象的好处是什么?
  2.   

在这种情况下,将提供Class的默认实现。这个默认实现只有一个实例,因为在接口中声明的所有字段都是隐式的public,static和final。这是一个 singleton 的示例。

这里一个可能的优点是您不必声明另一个命名类。而且由于目标显然是单身,因此命名类也不需要


  
      
  1. 是实现该接口的类的实例是否具有此接口[ sic ]的DEFAULT实例?
  2.   

请记住,SubtitleDecoderFactory是一个引用匿名类实例的字段。 DEFAULT的所有实现都可以访问此字段吗?是的,但不是特别因为他们正在实现接口。

由于接口中声明的所有字段都是公共字段,静态字段,并且最后一个SubtitleDecoderFactory字段是 constant (尽管不是 compile-time constant ) 。静态字段与该类关联,而不是与该类的实例关联。换句话说,任何可以“看到” DEFAULT的类都可以访问SubtitleDecoderFactory字段。例如:

DEFAULT