Множественное наследование для анонимного класса

Как анонимный класс может реализовать два (или более) интерфейса? В качестве альтернативы, как он может одновременно расширять класс, и реализовывать интерфейс? Например, я хочу создать объект анонимного класса, который расширяет два интерфейса:

    // 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).


person Community    schedule 01.05.2011    source источник
comment
К сожалению, вы должны сделать конструктор видимым в тех местах, где в противном случае он не был бы виден.   -  person Sridhar Sarnobat    schedule 02.11.2016


Ответы (5)


Анонимные классы должны что-то расширять или реализовывать, как и любой другой класс Java, даже если это просто java.lang.Object.

Например:

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

Здесь r — это объект анонимного класса, который реализует Runnable.

Анонимный класс может расширять другой класс, используя тот же синтаксис:

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

Чего вы не можете сделать, так это реализовать более одного интерфейса. Для этого вам нужен именованный класс. Однако ни анонимный внутренний класс, ни именованный класс не могут расширять более одного класса.

person skaffman    schedule 01.05.2011
comment
Я не думаю, что второе выражение является правильным. Вы уже объявили имя класса как SomeClass, оно больше не анонимно. Ознакомьтесь с этой ссылкой docstore.mik.ua/orelly/java-ent/ jnut/ch03_12.htm Когда вы создаете новый интерфейс, анонимный класс создается путем расширения класса Object и реализации этого интерфейса. Но пока вы создаете новый класс с первым написанным вами выражением, анонимный класс (на самом деле создается экземпляр этого анонимного класса) будет создан путем расширения этого класса. - person lixiang; 02.05.2012
comment
@youmiss: второе выражение создаст экземпляр анонимного класса, который расширяет SomeClass. Это все еще анонимно из-за {...}. - person skaffman; 02.05.2012
comment
Понятно, я проглядел {...}. - person lixiang; 02.05.2012

Анонимный класс обычно реализует интерфейс:

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
   }

 }
person extraneon    schedule 01.05.2011
comment
Мне нравится этот ответ, потому что он удобен для Google для людей, которые ищут реализацию 2 или более интерфейсов в анонимной реализации. - person L. Holanda; 25.06.2018

Анонимные классы всегда расширяют суперкласс или реализуют интерфейсы. Например:

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

Более того, хотя анонимный класс не может реализовать несколько интерфейсов, вы можете создать интерфейс, который расширяет другой интерфейс, и позволить вашему анонимному классу реализовать его.

person MByD    schedule 01.05.2011

Думаю, никто не понял вопроса. Я думаю, что этот парень хотел что-то вроде этого:

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.

Что вы можете сделать, так это использовать локальные классы внутри блоков методов:

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

        @Override
        public void anotherInterfaceMethod() { /*do something*/ }
    }
    return new LocalClass();
}
person thiagoh    schedule 16.11.2019
comment
Именно это и имел в виду ОП, ИМХО. - person DanielCuadra; 03.12.2019
comment
давая большие пальцы для ответа на заданный вопрос. что нормально для ТАК, что люди любят отвечать на то, что нужно спросить, а не на то, что было задано. - person mfaisalhyder; 09.04.2020

Анонимный класс расширяется или реализуется при создании своего объекта. Например:

Interface in = new InterFace()
{

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

}

Здесь анонимный класс реализует интерфейс.

Class cl = new Class(){

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

}

здесь анонимный класс расширяет абстрактный класс.

person trapedInBatcaveWithBAtman    schedule 15.06.2015
comment
Я не вижу разницы. Как твой отличается от моего. - person trapedInBatcaveWithBAtman; 15.06.2015
comment
хороший и компактный, чего мне не хватает в вашем ответе, так это слова «всегда или должен» :) - person kiedysktos; 29.01.2019