【问题标题】:Multiple inheritance for an anonymous class匿名类的多重继承
【发布时间】:2011-08-16 10:50:09
【问题描述】:

匿名类如何实现两个(或更多)接口?或者,它如何扩展一个类实现一个接口? 例如,我想创建一个扩展两个接口的匿名类对象:

    // Java 10 "var" is used since I don't know how to specify its type
    var lazilyInitializedFileNameSupplier = (new Supplier<String> implements AutoCloseable)() {
        private String generatedFileName;
        @Override
        public String get() { // Generate file only once
            if (generatedFileName == null) {
              generatedFileName = generateFile();
            }
            return generatedFileName;
        }
        @Override
        public void close() throws Exception { // Clean up
            if (generatedFileName != null) {
              // Delete the file if it was generated
              generatedFileName = null;
            }
        }
    };

然后我可以在 try-with-resources 块中将它用作 AutoCloseable 作为延迟初始化的实用程序类:

        try (lazilyInitializedFileNameSupplier) {
            // Some complex logic that might or might not 
            // invoke the code that creates the file
            if (checkIfNeedToProcessFile()) {
                doSomething(lazilyInitializedFileNameSupplier.get());
            }
            if (checkIfStillNeedFile()) {
                doSomethingElse(lazilyInitializedFileNameSupplier.get());
            }
        } 
        // By now we are sure that even if the file was generated, it doesn't exist anymore

我不想创建一个内部类,因为我绝对确定这个类不会在任何地方使用,除了我需要在其中使用它的方法(我也可能想要使用在该方法中声明的可能属于 var 类型的局部变量。

【问题讨论】:

  • 不幸的是,您必须让构造函数在其他地方可见。

标签: java multiple-inheritance anonymous-class


【解决方案1】:

我想没有人理解这个问题。我猜这家伙想要的是这样的:

return new (class implements MyInterface {
    @Override
    public void myInterfaceMethod() { /*do something*/ }
});

因为这将允许诸如多个接口实现之类的事情:

return new (class implements MyInterface, AnotherInterface {
    @Override
    public void myInterfaceMethod() { /*do something*/ }

    @Override
    public void anotherInterfaceMethod() { /*do something*/ }
});

这确实很好;但这在 Java 中是不允许的

可以做的是在方法块中使用local classes

public AnotherInterface createAnotherInterface() {
    class LocalClass implements MyInterface, AnotherInterface {
        @Override
        public void myInterfaceMethod() { /*do something*/ }

        @Override
        public void anotherInterfaceMethod() { /*do something*/ }
    }
    return new LocalClass();
}

【讨论】:

  • 没错,这就是 OP 的意图,恕我直言
  • 为回答所提问题竖起大拇指。这在 SO 上很正常,人们喜欢回答应该问什么而不是问什么。
【解决方案2】:

匿名类在创建其对象时正在扩展或实现 例如:

Interface in = new InterFace()
{

..............

}

这里匿名类正在实现接口。

Class cl = new Class(){

.................

}

这里的匿名类是在扩展一个抽象类。

【讨论】:

  • 我看不出有什么不同。你的和我的有什么不同。
  • 一个漂亮而紧凑的,我想念你的回答是像“总是”或“必须”这样的词:)
【解决方案3】:

匿名类必须扩展或实现某些东西,就像任何其他 Java 类一样,即使它只是 java.lang.Object

例如:

Runnable r = new Runnable() {
   public void run() { ... }
};

这里,r 是实现Runnable 的匿名类的对象。

匿名类可以使用相同的语法扩展另一个类:

SomeClass x = new SomeClass() {
   ...
};

你不能做的是实现多个接口。你需要一个命名类来做到这一点。然而,匿名内部类和命名类都不能扩展多个类。

【讨论】:

  • 我不认为第二个表达是正确的。您已经将类的名称声明为 SomeClass,它不再是匿名的。查看此链接docstore.mik.ua/orelly/java-ent/jnut/ch03_12.htm 当您“新建”一个接口时,通过扩展“Object”类并实现该接口来创建一个匿名类。但是,当您使用您编写的第一个表达式“新建”一个类时,将通过扩展该类来创建一个匿名类(实际上,它是该匿名类的一个实例)。
  • @youmiss:第二个表达式将创建一个匿名类的实例,它扩展了SomeClass。由于{...},它仍然是匿名的。
  • 我明白了,我忽略了 {...}。
【解决方案4】:
// The interface
interface Blah {
    void something();
}

...

// Something that expects an object implementing that interface
void chewOnIt(Blah b) {
    b.something();
}

...

// Let's provide an object of an anonymous class
chewOnIt(
    new Blah() {
        @Override
        void something() { System.out.println("Anonymous something!"); }
    }
);

【讨论】:

    【解决方案5】:

    匿名类总是扩展超类或实现接口。例如:

    button.addActionListener(new ActionListener(){ // ActionListener is an interface
        public void actionPerformed(ActionEvent e){
        }
    });
    

    另外,虽然匿名类不能实现多个接口,但是你可以创建一个接口扩展其他接口,让你的匿名类来实现。

    【讨论】:

      【解决方案6】:

      匿名类通常实现一个接口:

      new Runnable() { // implements Runnable!
         public void run() {}
      }
      
      JFrame.addWindowListener( new WindowAdapter() { // extends  class
      } );
      

      如果您的意思是您是否可以实现 2 或更多接口,我认为这是不可能的。然后,您可以创建一个将两者结合起来的私有接口。虽然我无法轻易想象为什么你会希望匿名类拥有它:

       public class MyClass {
         private interface MyInterface extends Runnable, WindowListener { 
         }
      
         Runnable r = new MyInterface() {
          // your anonymous class which implements 2 interaces
         }
      
       }
      

      【讨论】:

      • 我喜欢这个答案,因为它对于希望在匿名实现中实现 2 个或更多接口的人来说是谷歌友好的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-27
      • 2017-02-04
      相关资源
      最近更新 更多