Supporto linguistico per la delega (sintattica) in Java

2

La composizione sull'ereditarietà è una vecchia tendenza o addirittura uno stato dell'arte nella programmazione orientata agli oggetti. Sarebbe ancora più facile da usare in Java, se esistesse un supporto linguistico per la delega. I nostri IDE, come eclipse, consentono una facile generazione di metodi di delega, ma il risultato è un terribile disordine di codice. Mi piacerebbe piuttosto vedere qualcosa di simile

class ExtendedList<T> implements List<T> {
  List<T> values = new ArrayList<T>();
  delegate values.*;
  ...
}

dove delegate è una nuova parola chiave per la lingua che non è altro che una scorciatoia per ciò che l'IDE fa esplicitamente quando gli chiedi di delegare a tutti i metodi del campo values .

Potrei andare avanti per confrontare questo con l'ereditarietà e come il risultato potrebbe essere più o meno lo stesso, date le interfacce, ma più esplicito e permettendo una "eredità multipla" a grana fine, esplicita, ma questa discussione deve essere già avvenuta qualche volta nel passato in alcune mailing list Java. Tuttavia, sono riuscito a trovare solo link di 15 anni, ad esempio su beust.com e citeseer che descrive idee molto simili a quelle che ho in mente.

Penso che questo sia (a) veramente utile e (b) banale da implementare in un compilatore, tuttavia in 15 anni non è apparso nulla in Java.

Quindi la mia domanda è: cosa mi manca? C'è un ostacolo importante nell'attuazione di ciò di cui non sono a conoscenza?

Per inciso: mi piacerebbe avere dei buoni consigli su, ad esempio, Java / JCP / JSR / qualunque sia stato discusso. Non sono riuscito a trovarne.

Come richiesto, fammi provare un altro esempio:

class FileWithMetas extends OutputStream implements Map<String,String> {
  final OutputStream out;
  delegate out.*; // takes care of "extend OutputStream"
  final Map<String,String> metas = new HashMap<>();
  delegate metas.*; // takes care of "implements Map"
  public FileWithMetas(...) {
    this.out = new FileOutputStream(...);
  }
  @Override //explicitly re-implement the delegated out.close()
  public void close() {
    //serialize the metas, for example
    out.close(); // with classic inheritance this would be super.close()
  } 
}

Alla fine sembrerà molto più un'eredità multipla, ma come accennato: la delega è solo la sintassi dello zucchero che sostituisce i metodi di delega generati dall'IDE e, fatta eccezione per i messaggi di errore leggermente diversi, il compilatore dovrebbe comportarsi esattamente così. In effetti, penso che questo potrebbe sostituire completamente l'ereditarietà (non che io lo stia chiedendo) - dato che manteniamo le interfacce, ovviamente, che ci permettono di separare i tipi dall'implementazione.

    
posta Harald 08.02.2015 - 15:20
fonte

1 risposta

-3

Il tuo suggerimento non può gestire l'obiettivo di delega come null che andrebbe contro tutto ciò che è Java. Se si tenta di gestire questo forzando l'oggetto ad essere costante, allora è solo una variante meno leggibile dell'ereditarietà multipla. A proposito, l'ereditarietà multipla è già in Java 8.

Inoltre puoi ottenere facilmente lo stesso risultato rendendo pubblica la lista in questo modo:

class ExtendedList<T>{
  const public List<T> values = new ArrayList<T>();
}

Quindi è possibile utilizzare gli stessi metodi e quando si desidera utilizzare l'interfaccia è sufficiente passare direttamente l'oggetto List.

    
risposta data 08.02.2015 - 16:17
fonte

Leggi altre domande sui tag