En anonym klasse deklareres og instansieres i et uttrykk, og er enten en subklasse av en annen klasse eller så implementerer den et (og bare ett) grensesnitt. Hensikten med en anonym klasse vil ofte være en "quick-fix"/hurtig-implementasjon av en instans som implementerer et grensesnitt eller en klasse man vil gjøre forandringer på. Dette blir forhåpentligvis litt mer begripelig med noen eksempler.
Code Block |
---|
language | java |
---|
title | Syntax Subclassing |
---|
| // Usual instantiation of class
SomeClass instanceOfSomeClass = new SomeClass();
// Instantiation and declaration of
// an anonymous class
SomeClass myAnonymousClass = new SomeClass() {
private int newField;
@Override
public void someMethod() { ... }
public void newMethod() { ... }
};
// myAnonymousClass is a subclass of SomeClass |
| Code Block |
---|
language | java |
---|
title | Syntax interface |
---|
| // Usual usage of interface
public class SomeClass implements SomeInterface { ... }
SomeInterface instance = new SomeClass();
// Instantiation and declaration of an anonymous class
SomeInterface myAnonymousClass = new SomeInterface() {
@Override
public void requiredMethod1 { ... }
@Override
public void requiredMethod2 { ... }
};
// myAnonymousClass implements the required methods
// without beeing an instance of another class |
|
---|
Anonyme klasser til håndtering av hendelser
Dersom man har behov for å knytte en lytter til et objekt som produserer/sender ut eventer kan en anonym klasse brukes.
Dette gjelder spesielt dersom man ikke ønsker å spesifisere en helt ny klasse til å håndtere eventene en spesiell knapp sender ut.
Code Block |
---|
language | java |
---|
title | Special ActionListener |
---|
linenumbers | true |
---|
| // NOT USE OF ANONYMOUS CLASS
public class MySpecialActionListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
// Do something special
}
}
public class SomeClass implements ActionListener {
button1.addActionListener(this);
button2.addActionListener(this);
specialButton.addActionListener(new MySpecialActionListener());
public void actionPerformed(ActionEvent e) {
// Do something
}
} |
Eksempel v1 | Code Block |
---|
language | java |
---|
title | Anonymous ActionListener |
---|
linenumbers | true |
---|
| // USE OF ANONYMOUS CLASS
public class SomeClass implements ActionListener {
button1.addActionListener(this);
button2.addActionListener(this);
ActionListener actList = new ActionListener() {
public void actionPerformed(ActionEvent e) {
// Do something special
}
};
// actList is now an anonymous class
specialButton.addActionListener(actList);
public void actionPerformed(ActionEvent e) {
// Do something
}
}
|
Eksempel v2 |
---|
I v2 ser vi hvordan en anonym klasse kan deklareres og instansieres som en del av et uttrykk. Det er viktig å merke seg at det finnes flere "workarounds" for eksempelet ovenfor med hensyn på en knapp med en spesiell actionPerformed-metode, men her brukes anonyme klasser som en mulig løsning.
Inline implementasjon av grensesnitt
Deklarasjonen (og instansieringen) av den nye actionlisteneren på linje 8-13 i v2 av eksempelet ovenfor kan kalles en inline implementasjon av ActionListener-grensesnittet.
Om man vil deklarere en ny klasse som skal implementere et enkelt grensesnitt trenger man ikke nødvendigvis lage en egen klasse, men heller bruke en anonym klasse på samme måte som ovenfor.
Et annet eksempel:
Code Block |
---|
language | java |
---|
title | Runnable |
---|
| public class SuperfastRunnable implements Runnable {
// Required to implement
public void run() {
// Do something
}
}
public static void main(String[] args) {
// code..
SuperfastRunnable sfr = new SuperfastRunnable();
// code..
} |
| Code Block |
---|
language | java |
---|
title | Anonymous Runnable |
---|
| public static void main(String[] args) {
// code..
Runnable r = new Runnable() {
// Required to implement
public void run() {
// Do something
}
};
// code..
} |
|
---|
Igjen kan man spare seg for bryet med å lage en ny klasse om man bare trenger én instans av den på et/få sted(er) i koden. Pass dog på; mange anonyme klasser kan fort gjøre koden uoversiktlig.
Inline overriding av metoder ved arv
På samme måte som med implementasjon av grensesnitt, kan man også arve klasser inline ved å lage en anonym klasse. Dette kan være særlig nyttig dersom man f.eks. ønsker å lage én instans av en klasse, som skal override en eller få metoder. Se eksempel under.
Code Block |
---|
language | java |
---|
title | Subclass TextField |
---|
| TextField sum = new TextField() {
@Override
public void replaceText(int start, int end, String text) {
if (!text.matches("[a-z, A-Z]")) {
super.replaceText(start, end, text);
}
label.setText("Enter a numeric value");
}
@Override
public void replaceSelection(String text) {
if (!text.matches("[a-z, A-Z]")) {
super.replaceSelection(text);
}
}
}; |
|
---|
Eksempelet ovenfor viser hvordan en instans, sum, subklasser TextField og inline skriver over metodene replaceText og replaceSelection. Tekstfeltet sum er ment som et felt som bare vil ha input i form av numeriske verdier, og metoden som setter teksten forandres slik at den varsler dersom noen skriver tekst i feltet.