2009-05-19 7 views
23

Diciamo che ho una classe Foo che implementa un'interfaccia come MouseListener. L'interfaccia MouseListener è composta da cinque metodi, ma desidero sovrascrivere solo uno di essi (mouseClicked()). Esiste un modo standard e idiomatico per formattare gli altri metodi?Esiste un idioma in Java per i metodi vuoti che esistono per soddisfare un'interfaccia?

La mia inclinazione è stato quello di scrivere il seguente:

@Override 
public void mouseClicked(MouseEvent e) { 
    // (...) <-- actual code here 
} 

@Override 
public void mouseEntered(MouseEvent e) { 
    // Do nothing. Exists to satisfy MouseListener interface. 
} 

@Override 
public void mouseExited(MouseEvent e) { 
    // Do nothing. Exists to satisfy MouseListener interface. 
} 

@Override 
public void mousePressed(MouseEvent e) { 
    // Do nothing. Exists to satisfy MouseListener interface. 
} 

@Override 
public void mouseReleased(MouseEvent e) { 
    // Do nothing. Exists to satisfy MouseListener interface. 
} 

Io sono un fan di rendere esplicito che i metodi sono intenzionalmente vuota piuttosto che accidentalmente lasciato così, ma io non sono pazzo per tutto lo spazio verticale rinunciato praticamente a nulla. Ho visto anche il seguente formato:

public void mouseClicked(MouseEvent e) { 
    // (...) <-- actual code here 
} 

public void mouseEntered(MouseEvent e) {} 
public void mouseExited(MouseEvent e) {} 
public void mousePressed(MouseEvent e) {} 
public void mouseReleased(MouseEvent e) {} 

Sono generalmente OK con questo e capisco l'intento dell'autore, ma si fa veramente brutto quando vengono aggiunti i (recommended) @Override annotazioni.

Non sono un codificatore Java particolarmente esperto, quindi ho pensato di chiedere se c'era una convenzione. Pensieri?

+1

Sei a conoscenza della classe MouseAdapter, giusto? http://java.sun.com/javase/6/docs/api/java/awt/event/MouseAdapter.html –

risposta

5

Usa MouseAdapter

+7

Mentre questa risposta è corretta, non affronta lo spirito della domanda che è ciò che deve essere fatto quando viene implementata solo una parte dell'interfaccia. –

+6

Chiede di essere convinto, non quale interfaccia implementare. –

+0

Estendere questa classe per creare un listener MouseEvent e sovrascrivere i metodi per gli eventi di interesse. (Se si implementa l'interfaccia MouseListener, è necessario definire tutti i metodi presenti in essa. Questa classe astratta definisce i metodi null per tutti, quindi è possibile solo definire i metodi per gli eventi che si interessano.) Http: // java. sun.com/j2se/1.4.2/docs/api/java/awt/event/MouseAdapter.html –

8

lo faccio lo stesso modo di fare, se c'è niente là lasciare in una sola riga. Magari inserire un commento in cima a un grande blocco di "one-liner dell'implementazione".

1

MouseAdapter è ottimo per questo caso specifico e l'idioma dell'adattatore è ottimo in generale. Un adattatore ha implementazioni vuote di tutti i metodi dell'interfaccia, consentendo di sottoclasse e implementare solo quei metodi che sono rilevanti per la tua classe. In alternativa l'adattatore potrebbe, come suggerisce Andrew Hare, lanciare NotImplementedException.

6

In questo caso particolare, è necessario seguire il consiglio di wilums2 e estendere MouseAdapter invece di implementare MouseListener. Lo scopo di queste classi di adattatori è che non è necessario fornire implementazioni vuote quando si implementano solo alcuni dei metodi di un'interfaccia.

Più in generale, la risposta breve è 'no', non v'è alcuna convenzione standard per il modo di documentare i metodi vuoti, anche se io di solito uso qualcosa come

@Override 
void foo() { 
    // No implementation necessary 
} 
1

Lo scopo di un ascoltatore deve essere notificata di alcuni eventi. Se l'interfaccia del listener contiene più callback del metodo di cui hai bisogno, ignora solo quelli che non ti interessano. Nel tuo caso MouseAdapter è stato progettato per questo scopo esatto. Do non gettare UnsupportedOperationException poiché il chiamante probabilmente non si aspetta l'eccezione. Inoltre, molto probabilmente viola il contratto dell'interfaccia dell'ascoltatore poiché ogni metodo dovrebbe essere implementato.

+0

Probabilmente anche il chiamante non si aspetta che la funzione non faccia nulla. Non facendo nulla, hai violato il contratto di interfaccia, che porterà a bug strani ed estremamente difficili da debugare. Direi di lanciare l'errore in modo che il problema si presenti immediatamente durante il test/l'uso. Se non si riesce a generare un errore, si dovrebbe almeno segnalare un avviso che è stata chiamata un'operazione non supportata. Non fare assolutamente nulla, può essere un errore costoso (in fase di debugging dei bug risultanti). (In caso di dubbio, almeno registrarlo in modo che ci sia almeno un buon suggerimento per i bug che provoca) – Tezra

0

Immagino che lo descriverò come "implementazione non operativa" o forse userò il termine "adattatore". Come altri hanno notato, Java fornisce una classe MouseAdapter che fa quello che vuoi. A rigor di termini, non ricade nella definizione del pattern Adapter, che trasforma una API in un'altra, ma sinceramente tendo ad essere pragmatico nel nominare tali cose.

Probabilmente la cosa più importante da fare è essere chiaro che si intende che il metodo non abbia implementazione. Nel caso specifico dello MouseAdapter, probabilmente non si vuole andare in giro a lanciare UnsupportedOperationException, ma in generale, è probabilmente un buon segnale che non si intende fornire un'implementazione.Di solito è necessario un commento nel codice sorgente (o, meglio, nella documentazione del metodo) per spiegare perché non si sta implementando completamente l'interfaccia.

0

Non penso che sia particolarmente importante. Per i miei gusti personali non mi piace vedere la parentesi graffa di chiusura successiva all'apertura, che dà:

public void mouseEntered(MouseEvent e) { 
} 

un po 'vuota, ma va bene. Nel caso di un valore di ritorno possiamo farlo sembrare coerente, che non si ottiene con lo stile [].

Ma quando si tratta di rari casi in loop, mi piace un punto e virgola in là:

// Made up example. 
while (++i < len && str.charAt(i) != '\0') { 
    ; 
} 

che darebbe:

public void mouseEntered(MouseEvent e) { 
    ; 
} 

Nel caso di catch clausole, che ci si meglio avere una buona scusa in un commento (magari lasciando cadere un'interruzione).

5

In generale, ciò che si sta parlando è un'estensione del modello oggetto nullo. Stai definendo un oggetto Null e lo estendi ignorando solo i metodi che ti interessano.

Come esempio di un modo per automatizzare questo, nelle mie annotazioni di bean JavaDude (http://code.google.com/p/javadude/wiki/Annotations), è possibile fare qualcosa di simile al seguente. [NOTA: non raccomanderei di farlo per MouseListener, poiché MouseAdapter esiste già e puoi solo sottoclassi ... Quanto segue è utile per altre interfacce di grandi dimensioni in cui desideri implementare solo alcuni metodi selezionati]

@Bean(nullObjectImplementations = @NullObject(type=MouseListener.class)) 
public class MyMouseHandler extends MyMouseHandlerGen { 
    public void mouseClicked(MouseEvent e) { 
     // your handling of a MouseClick 
    } 
} 

è quindi possibile utilizzare MyMouseHandler per gestire il click =

Nota:. MouseAdapter era un davvero cattiva scelta per il nome della classe nella JRE/JDK. Non è un'istanza del modello dell'adattatore GoF; è davvero un'implementazione Null Object di un MouseListener.

BTW: Si può mettere @Override sulla stessa linea della dichiarazione di metodo - per il tuo esempio è possibile avere

@Override public void mousePressed(MouseEvent e) { /* not needed */ } 
// et al 
0

Ho trovato questo durante la ricerca per questa domanda esatta. Sto usando su scroll dove ho bisogno di onScrollStateChanged ma non onScroll. Mi è stato appoggiato verso:

@Override 
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, 
      int totalItemCount) { 
    return;   
} 

Tuttavia, mi piace il secondo esempio si dà (con le parentesi graffe sui stessa linea). È compatto e pulito e può costantemente esprimere l'idea che sia intenzionalmente lasciato in bianco.

Edit: questo è quello che ho optato per:

@Override 
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, 
      int totalItemCount) {return;} 

Questo ha un sacco di parametri in modo non sembra così bello come su una sola riga, ma si ottiene l'idea.

2

Ci sono diversi modi per farlo. Oracle java conventions p6.4 (pagina 11) dice che i metodi vuoti dovrebbe essere simile

public void empty() {} 

C'è anche un documento scritto nel 2003 Steve Yohanan formica si dice

public void empty() 
{ 
} 

Anche se non ho trovato alcuna convenzione per "vuoto metodo come interfaccia ". Quindi, come conclusione, non esiste un modo standardizzato per farlo. Alcuni preferiscono lasciare un commento, alcuni preferiscono renderlo a riga singola, altri lo scrivono come qualsiasi altro metodo con il corpo vuoto.

+0

Grazie per aver effettivamente fornito un collegamento alle convenzioni di codifica come richiesto dall'OP. – amertkara

Problemi correlati