Domanda

sto scrivendo (o meglio, completando) una "estensione" di Java che aiuterà la programmazione ruolo.
Traduco il mio codice di codice Java con JavaCC. I miei compilatori aggiungono ad ogni classe dichiarata po 'di codice. Ecco un esempio per essere più chiaro:

MyClass extends String implements ObjectWithRoles { //implements... is added
    /*Added by me */
    public setRole(...){...}
    public ...
    /*Ends of stuff added*/
    ...//myClass stuff
}

Si aggiunge Implementa .. ed i metodi necessari ad ogni singola classe si dichiara. Piuttosto grossolana, isnt'it?

Sarà meglio se scrivo i miei metodi in una classe e tutto classe estende quello .. ma .. se la classe estende già un'altra classe (proprio come l'esempio)?

Non voglio creare una sorta di wrapper che gestire i ruoli, perché io non voglio che il programmatore deve conoscere molto di più di Java, alcune nuove parole riservate e il loro uso.

La mia idea era quella di estende java.lang.Object .. ma non si può. (Giusto?)
Altre idee?

Sono nuovo qui, ma seguo questo sito quindi grazie per la lettura e tutte le risposte che date! (Mi scuso per l'inglese, io sono italiana)

È stato utile?

Soluzione

Se è solo come un progetto di "ricerca" in cui si desidera esplorare come tale estensione avrebbe funzionato, è possibile fornire una propria implementazione della classe Object. Basta copiare l'implementazione oggetto esistente, aggiungere il metodo di setRole ecc, e dare -Xbootclasspath:.:/usr/lib/jvm/java-6-sun/jre/lib/rt.jar come parametro al comando java. (Cercherò API-classi . prima di guardare nel vero rt.jar.)

Altri suggerimenti

Si dovrebbe considerare l'utilizzo di composizione piuttosto che ereditarietà per risolvere questo problema; in questo modo è possibile fornire le funzionalità necessarie senza usare il vostro "one-shot" alla ereditarietà.

Per esempio, il JDK fornisce una PropertyChangeSupport di classe, che può essere utilizzato per gestire PropertyChangeListeners e la cottura dei PropertyChangeEvents. Nelle situazioni in cui si desidera scrivere una classe che gli incendi PropertyChangeEvents si potrebbe integrare una variabile di istanza PropertyChangeSupport e delegare tutte le chiamate di metodo a quella. Questo evita la necessità di ereditarietà e significa che è possibile integrare una gerarchia di classe esistente con nuove funzionalità.

public class MyClass extends MySuperClass {
  private final PropertyChangeSupport support;

  public MyClass() {
    this.support = new PropertyChangeSupport(this);
  }

  public void addPropertyChangeListener(PropertyChangeListener l) {
    support.addPropertyChangeListener(l);
  }

  protected void firePropertyChangeEvent() {
    PropertyChangeEvent evt = new ...
    support.firePropertyChangeEvent(evt);
  }
}
  • è possibile estendere Object -. Ogni classe estende
  • ti sembra di bisogno di qualcosa come l'ereditarietà multipla - non è una cosa del genere in Java
  • se si desidera aggiungere funzionalità, composizione uso oggetto. Vale a dire,

    YourClass extends Whatever implements ObjectWithRoles {
        private RoleHandler roleHandler;
        public RoleHandler getRoleHandler() {..} // defined by the interface
    }
    

E poi tutti i metodi vengono inseriti nella RoleHandler

Se si sta parlando di aggiungere un ruolo a tutti i vostri oggetti Vorrei anche prendere in considerazione una soluzione di annotazione-based. Faresti annotare le classi con qualcosa come @Role ( "Utente"). In un'altra classe è possibile estrarre il valore ruolo e utilizzarlo.

Credo che sarebbe bisogno di un'annotazione con runtime di ritenzione e si può controllare, tempo di esecuzione, se l'annotazione è presente con la riflessione e ottenere che l'annotazione utilizzando getAnnotation . Credo che questo sarebbe molto più pulito di quanto si estende automaticamente tutte le classi.

Credo che ci sono alcuni quadri che utilizzano esattamente tale soluzione una, quindi non ci dovrebbe essere codice di esempio da qualche parte.

Se si sta facendo quello che stai facendo, allora eredità non è probabilmente il linguaggio corretto. Si può prendere in considerazione il modello di decoratore, per cui si costruisce una classe che prende come parametro qualche altra classe con meno funzionalità, e aggiunge alcune funzionalità aggiuntive ad esso, delegando alla classe esistente per le funzionalità che già esiste. Se l'implementazione è comune a molti dei vostri decoratori, si consiglia di valutare l'ipotesi che la funzionalità di classe che può essere condiviso e al quale è possibile delegare per tutte le vostre decoratori. A seconda di che cosa avete bisogno, doppio spedizione o di riflessione può essere opportuno al fine di rendere simili, ma non proprio la stessa decoratori per una grande varietà di classi.

Inoltre, come è stato sottolineato nei commenti, String è dichiarata "finale" e, pertanto, non può essere estesa. Quindi, si dovrebbe davvero prendere in considerazione una soluzione di cui si delega / oggetti decorare. Ad esempio, si potrebbe avere qualche oggetto che avvolge una corda e fornisce l'accesso alla stringa tramite getString () o toString (), ma poi aggiunge la funzionalità aggiuntiva sulla parte superiore della classe String.

Se si desidera solo per associare alcuni oggetti con attributi aggiuntivi, utilizzare un Mappa (ad esempio HashMap ).

Che cosa si vuole veramente fare sarebbe scimmia patching , cioè cambiare il comportamento di esistere classi senza modificare il loro codice.

Purtroppo, Java non supporta questo, né le cose come mixins che potrebbe essere utilizzato in alternativa . Quindi, a meno che non siete disposti a passare ad un linguaggio più dinamico come Groovy, dovrete convivere con soluzioni meno eleganti come composizione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top