Come applichiamo un'interfaccia bidirezionale con un'interfaccia Java?


Java non consente metodi privati o protetti, quindi come possiamo garantire che gli implementatori di un'interfaccia bidirezionale chiamino i metodi necessari?

Diciamo che abbiamo un'interfaccia IModelListener come segue:

public interface IModelListener
{   
    public void handleChannelUpdate(int channel);
}

Quindi abbiamo un client ViewControl come segue:

public class ViewControl implements IModelListener

Gli oggetti ViewControl funzioneranno finché ci ricordiamo di avere ViewControl chiamare questo:

model.registerChannelListener(this);

Se Java consentiva metodi protetti o privati in un'interfaccia, potremmo semplicemente modificare IModelListener a:

public interface IModelListener
{   
    public void handleChannelUpdate(int channel);
    private void registerChannelListener( );
}

Come si può raggiungere questo obiettivo? Ci sono annotazioni che lo farebbero?

Java non supporta l'ereditarietà multipla, quindi se i client / implementatori sono già una classe derivata (tipica), l'utilizzo di una classe astratta non è un'opzione.

Grazie per l'aiuto, Jeff

Author: Jeff J, 2014-02-27

6 answers

Probabilmente ti manca il concetto di interfacce. Non può contenere metodi privati o protetti, perché il ruolo di un'interfaccia è quello di fornire insieme accessibile di metodi. Probabilmente potresti, d'altra parte, dare un'occhiata alle classi astratte.

Quello di cui hai bisogno è probabilmente questo:

public abstract class AbstractViewControler implements IModelListener {

    protected abstract void registerChannelListener();

    protected AbstractViewControler() {
        this.registerChannelListener();
    }
}

E poi:

public class MyViewControler extends AbstractViewControler {

    protected void registerChanelListener() {
        //- Do what you need here.
    }
}

E dopo solo:

IModelListener listner = new MyViewControler();
 3
Author: Cromax, 2014-02-27 14:06:23

Un'interfaccia è un modo per fornire un contratto pubblico agli utenti della classe che implementano l'interfaccia. Il modo in cui viene implementata la classe non ha importanza, purché aderiscano al contratto. Pertanto, non ha senso avere metodi privati in un'interfaccia.

 1
Author: nhaarman, 2014-02-27 13:11:13

Quello che vuoi è applicare un comportamento predefinito sulla tua classe - in Java, le classi astratte sono il luogo in cui formulare il comportamento predefinito ereditato da tutte le classi estendenti (vedere il modello di progettazione del metodo template per un'applicazione di questo). Le interfacce descrivono solo come si comportano esternamente gli oggetti e come possono essere utilizzati da altri.

 0
Author: Smutje, 2014-02-27 13:08:38

Interfaccia in java destinato a fornire la firma della funzionalità di interfaccia in media di firma che si implementa nelle classi in modo che non dovrebbe essere privato.

Your need: puoi avere un metodo astratto con alcune istruzioni predefinite che desideri.

Dove è possibile avere tutti i tipi di accesso specify.

 0
Author: RTA, 2014-02-27 13:12:36

In Java, non è possibile farlo utilizzando solo un'interfaccia.

Se si desidera ottenere una sorta di "autobinding" (ovvero chiamare model.registerChannelListener(this); automaticamente su tutti gli oggetti pertinenti), è necessario che tali oggetti implementino un'interfaccia vuota, recuperino l'elenco di tutte le istanze delle classi che lo implementano tramite introspezione e iterino su di essi.

Puoi farlo periodicamente o in qualche punto specifico del programma. Puoi anche usare un'annotazione @ interface per aggiungere un po' zucchero sintattico.

Potresti anche voler invertire il flusso e creare oggetti usando dependency injection e/o una factory, in modo da avere quel metodo chiamato "automagicamente" subito dopo la creazione (come con @PostConstruct).

 0
Author: Stefano Sanfilippo, 2014-02-27 13:41:24

Le interfacce sono il posto sbagliato in cui cercare.

La soluzione usuale in Java per problemi come questo è avere un metodo in entrambi gli oggetti che restituisce l'altro:

public class ViewControl {
    public IModel getModel() {...}
}

Il metodo può quindi assicurarsi che il modello e la vista siano collegati correttamente. Ora immagino che non vuoi davvero accoppiare la vista e il modello. La soluzione è quindi definire un nuovo tipo ViewModel che delega solo al modello reale (la maggior parte degli IDE consente di creare tipi delegati con il mouse 3-5 clic):

public class ViewControl {
    public ViewModel getViewModel( IModel model ) {...}
}

Dovresti essere in grado di spostare questo codice in una classe di visualizzazione di base (abstract) da cui tutte le viste ereditano.

 0
Author: Aaron Digulla, 2014-02-27 13:54:10