Hatta mümkün mü?
Yanıtlar:
anonim bir işlevi kastediyorsanız ve Java 8'den önceki bir Java sürümünü kullanıyorsanız, o zaman kısaca hayır. ( Java 8+ kullanıyorsanız lambda ifadeleri hakkındaki bilgileri okuyun )
Ancak, aşağıdaki gibi bir işleve sahip bir arayüz uygulayabilirsiniz:
Comparator<String> c = new Comparator<String>() {
int compare(String s, String s2) { ... }
};
ve bunu neredeyse anonim bir işlev elde etmek için iç sınıflarla kullanabilirsiniz :)
İşte anonim bir iç sınıf örneği.
System.out.println(new Object() {
@Override public String toString() {
return "Hello world!";
}
}); // prints "Hello world!"
İşte bu kadar çok kullanışlı değildir, ancak bir anonim iç bu sınıfın bir örneğini nasıl oluşturulacağını gösterir extends Object
ve @Override
onun toString()
yöntemine.
Anonim iç sınıflar, çok fazla interface
yeniden kullanılamayabilecek (ve bu nedenle kendi adlandırılmış sınıfına yeniden düzenleme yapmaya değmeyen) bir uygulamaya ihtiyacınız olduğunda çok kullanışlıdır . Öğretici bir örnek, bir gelenek kullanmaktırjava.util.Comparator<T>
sıralama için .
İşte bir String[]
temel alarak nasıl sıralayabileceğinize dair bir örnek String.length()
.
import java.util.*;
//...
String[] arr = { "xxx", "cd", "ab", "z" };
Arrays.sort(arr, new Comparator<String>() {
@Override public int compare(String s1, String s2) {
return s1.length() - s2.length();
}
});
System.out.println(Arrays.toString(arr));
// prints "[z, cd, ab, xxx]"
Burada kullanılan çıkarma yoluyla karşılaştırma hilesine dikkat edin. Bu tekniğin genel olarak bozulmuş olduğu söylenmelidir: yalnızca taşmayacağını garanti edebildiğinizde uygulanabilir (durum böyledir.String
uzunluklarda ).
EventListener
, ortalama Swing uygulamasında (alt) uygulamalar olarak bulunabilir .
Linked
kenar çubuğunu ekledi , bu yüzden onu kullanmak için elimden gelenin en iyisini yapıyorum.
Java 8'de lambda ifadesinin tanıtılmasıyla artık anonim yöntemlere sahip olabilirsiniz.
Diyelim ki bir sınıfım var Alpha
ve e-postaları Alpha
belirli bir koşulda filtrelemek istiyorum . Bunu yapmak için bir Predicate<Alpha>
. Bu, test
kabul eden Alpha
ve döndüren bir yönteme sahip işlevsel bir arayüzdür.boolean
.
Filtre yönteminin şu imzaya sahip olduğunu varsayarsak:
List<Alpha> filter(Predicate<Alpha> filterPredicate)
Eski anonim sınıf çözümüyle şunun gibi bir şeye ihtiyacınız olacaktı:
filter(new Predicate<Alpha>() {
boolean test(Alpha alpha) {
return alpha.centauri > 1;
}
});
Java 8 lambdas ile şunları yapabilirsiniz:
filter(alpha -> alpha.centauri > 1);
Daha ayrıntılı bilgi için Lambda İfadeleri eğitimine bakın
Mevcut bir tipin arayüzünü uygulayan veya genişleten anonim iç sınıflar, diğer cevaplarda yapılmıştır, ancak birden fazla yöntemin uygulanabileceğini belirtmek gerekir (örneğin JavaBean tarzı olaylarla).
Biraz tanınan bir özellik, anonim iç sınıfların bir adı olmasa da, bir türlerinin olmasıdır. Arayüze yeni yöntemler eklenebilir. Bu yöntemler yalnızca sınırlı durumlarda çağrılabilir. Esas olarak doğrudan new
ifadenin kendisi ve sınıf içinde (örnek başlatıcıları dahil). Yeni başlayanların kafasını karıştırabilir, ancak özyineleme için "ilginç" olabilir.
private static String pretty(Node node) {
return "Node: " + new Object() {
String print(Node cur) {
return cur.isTerminal() ?
cur.name() :
("("+print(cur.left())+":"+print(cur.right())+")");
}
}.print(node);
}
(Başlangıçta kullanarak bu yazmış node
ziyade cur
içinde print
yöntemle. Say NO "örtük yakalamanın final
" yerli? )
node
final
burada beyan edilmelidir .
cur
.
"Node" +
ikinci bir yöntemi gerekli kılmak için biraz ilgisiz olanı not edin ). / Benim bir adım yok. Belki bir adlandırma "anket" (CW) sorusu oluşturabilir ve onu unutulmaya itebilirim.
Evet, en son java olan sürüm 8'i kullanıyorsanız. Java8, önceki sürümlerde imkansız olan anonim işlevleri tanımlamayı mümkün kılar.
Anonim fonksiyonları, sınıfları nasıl tanımlayabileceğimizi öğrenmek için java dokümanlarından örnek alalım
Aşağıdaki örnek, HelloWorldAnonymousClasses, frenchGreeting ve spanishGreeting yerel değişkenlerinin başlatma ifadelerinde anonim sınıflar kullanır, ancak englishGreeting değişkeninin başlatılması için yerel bir sınıf kullanır:
public class HelloWorldAnonymousClasses {
interface HelloWorld {
public void greet();
public void greetSomeone(String someone);
}
public void sayHello() {
class EnglishGreeting implements HelloWorld {
String name = "world";
public void greet() {
greetSomeone("world");
}
public void greetSomeone(String someone) {
name = someone;
System.out.println("Hello " + name);
}
}
HelloWorld englishGreeting = new EnglishGreeting();
HelloWorld frenchGreeting = new HelloWorld() {
String name = "tout le monde";
public void greet() {
greetSomeone("tout le monde");
}
public void greetSomeone(String someone) {
name = someone;
System.out.println("Salut " + name);
}
};
HelloWorld spanishGreeting = new HelloWorld() {
String name = "mundo";
public void greet() {
greetSomeone("mundo");
}
public void greetSomeone(String someone) {
name = someone;
System.out.println("Hola, " + name);
}
};
englishGreeting.greet();
frenchGreeting.greetSomeone("Fred");
spanishGreeting.greet();
}
public static void main(String... args) {
HelloWorldAnonymousClasses myApp =
new HelloWorldAnonymousClasses();
myApp.sayHello();
}
}
Anonim Sınıfların Sözdizimi
FrenchGreeting nesnesinin somutlaştırılmasını düşünün:
HelloWorld frenchGreeting = new HelloWorld() {
String name = "tout le monde";
public void greet() {
greetSomeone("tout le monde");
}
public void greetSomeone(String someone) {
name = someone;
System.out.println("Salut " + name);
}
};
Anonim sınıf ifadesi aşağıdakilerden oluşur:
new
operatörUygulanacak arabirimin veya genişletilecek sınıfın adı. Bu örnekte, anonim sınıf HelloWorld arabirimini uyguluyor.
Normal bir sınıf örneği oluşturma ifadesi gibi, bir kurucuya yönelik argümanları içeren parantezler. Not: Bir arabirim uyguladığınızda, yapıcı yoktur, bu nedenle bu örnekte olduğu gibi boş bir parantez çifti kullanırsınız.
Sınıf beyannamesi kuruluşu olan bir kuruluş. Daha spesifik olarak, vücutta yöntem bildirimlerine izin verilir ancak ifadelere izin verilmez.