Anonim bir sınıf için çoklu miras


98

Anonim bir sınıf iki (veya daha fazla) arabirimi nasıl uygulayabilir? Alternatif olarak, nasıl olabilir hem bir sınıf genişletmek ve bir arabirim uygulamak? Örneğin, iki arayüzü genişleten bir anonim sınıf nesnesi oluşturmak istiyorum:

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

Daha sonra bunu bir kaynakla deneme bloğunda AutoCloseabletembel başlatılmış bir yardımcı program sınıfı olarak kullanabilirim:

        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

Kesinlikle emin bu sınıf yönteminin dışında her yerde kullanılan ı kullanmak için gerekmez (ve de olmayacak çünkü ben bir iç sınıfı oluşturmak istemiyoruz olabilir yerel değişkenler kullanmak istediğinizi yöntemde o kudreti beyan olması var) türü.


Maalesef, kurucuyu aksi halde olmayacak yerlerde görünür kılmalısınız.
Sridhar Sarnobat

Yanıtlar:


99

Anonim sınıfları gerekir sadece olsa bile, başka bir Java sınıfı gibi bir şey uzatmak veya uygulamak java.lang.Object.

Örneğin:

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

Burada, ruygulayan anonim bir sınıfın nesnesidir Runnable.

Anonim bir sınıf, aynı sözdizimini kullanarak başka bir sınıfı genişletebilir:

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

Yapamayacağınız şey, birden fazla arayüz uygulamaktır. Bunu yapmak için adlandırılmış bir sınıfa ihtiyacınız var. Ne anonim bir iç sınıf ne de adlandırılmış bir sınıf birden fazla sınıfı genişletemez.


1
İkinci ifadenin doğru olduğunu sanmıyorum. Sınıfın adını zaten SomeClass olarak ilan ettiniz, artık anonim değil. Bu bağlantıya göz atın docstore.mik.ua/orelly/java-ent/jnut/ch03_12.htm Bir arayüz "yeni" olduğunuzda, "Object" sınıfını genişleterek ve bu arayüzü uygulayarak anonim bir sınıf oluşturulur. Ancak, yazdığınız ilk ifadeyle bir sınıfı "yenilerken", o sınıfı genişleterek anonim bir sınıf (aslında, bu anonim sınıfın yaratıldığı bir örnektir) oluşturulacaktır.
lixiang

8
@youmiss: 2. ifade, genişleyen anonim bir sınıfın bir örneğini yaratacaktır SomeClass. Nedeniyle hala anonimdir {...}.
skaffman

1
Görüyorum, {...} göz ardı ettim.
lixiang

36

Anonim bir sınıf genellikle bir arabirim uygular:

new Runnable() { // implements Runnable!
   public void run() {}
}

JFrame.addWindowListener( new WindowAdapter() { // extends  class
} );

2 veya daha fazla arayüz uygulayıp uygulayamayacağınızı kastediyorsanız , bence bu mümkün değil. Daha sonra ikisini birleştiren özel bir arayüz oluşturabilirsiniz. Yine de neden anonim bir sınıfın buna sahip olmasını istediğinizi tahmin edemiyorum:

 public class MyClass {
   private interface MyInterface extends Runnable, WindowListener { 
   }

   Runnable r = new MyInterface() {
    // your anonymous class which implements 2 interaces
   }

 }

Bu cevabı beğendim çünkü bir uygulamada 2 veya daha fazla arayüz uygulamak isteyen insanlar için google dostu.
L. Holanda

16

Anonim sınıflar her zaman üst sınıfı genişletir veya arabirimleri uygular. Örneğin:

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

Ayrıca, anonim sınıf birden çok arabirim uygulayamasa da, diğer arabirimi genişleten bir arabirim oluşturabilir ve anonim sınıfınızın onu uygulamasına izin verebilirsiniz.


13

Sanırım kimse soruyu anlamadı. Sanırım bu adamın istediği şey şuydu:

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

çünkü bu, çoklu arayüz uygulamaları gibi şeylere izin verir:

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

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

bu gerçekten güzel olurdu; ancak Java'da buna izin verilmez .

Ne yapabilirsiniz yapmak kullanmaktır yerel sınıfları yöntemi blokların içinde:

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

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

Kesinlikle, OP'nin
IMHO'yu kastettiği buydu

sorulan soruyu cevaplamak için başparmak verin. SO'da insanların ne sorulduğunu değil ne sorulması gerektiğini yanıtlamayı sevmeleri normaldir.
mfaisalhyder

3
// 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!"); }
    }
);

1

Anonim bir sınıf, nesnesini oluştururken genişletiyor veya uyguluyor Örneğin:

Interface in = new InterFace()
{

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

}

Burada anonim sınıf, Interface'i uyguluyor.

Class cl = new Class(){

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

}

burada anonim Sınıf, soyut bir Sınıfı genişletiyor.


Farkı görmüyorum. Seninki benimkinden ne kadar farklı.
trapedInBatcaveWithBAtman

güzel ve derli
toplu bir
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.