2015-04-26 6 views
6

Il modulo di estensione di groovy presenta una forma ibrida di funzionalità di ereditarietà di java? Perché il modulo di estensione deve essere dichiarato statico?Modulo di estensione di Groovy rispetto all'eredità di java

+0

Pensare ai moduli di estensione in termini di ereditarietà è una cattiva idea. Estendono una particolare classe con un comportamento aggiuntivo: quindi stanno modificando una gerarchia ereditaria esistente piuttosto che contribuire ad essa ... ma il loro contesto è veramente focalizzato su una singola classe (quindi, ancora una volta, ignora l'ereditarietà). Altre lingue hanno un costrutto simile come parte della definizione del tipo di prima classe (Go, Scala, Kotlin ...). Sono statici perché sono definiti al di fuori del loro ambiente di runtime: in questo modo, invece, ricevono l'istanza come argomento (di nuovo simile all'approccio di altre lingue). –

risposta

0

Risposta breve è penso di si. È un po 'difficile rispondere in modo chiaro, poiché l'ereditarietà dei metodi di estensione viene eseguita completamente dal runtime (e dal compilatore statico). In quanto tale, non ha nulla a che fare con il modo in cui Java eredita.

Per rispondere alla seconda domanda ... Sono statici, perché per le situazioni in cui è necessario indicare si utilizza di solito la meta classe. I metodi di estensione sono inizialmente pensati come metodi di convenienza o per rendere l'API più Groovy. In quanto tali, sono una forma speciale di metodi aggiunti alla meta classe. Puoi vederli come versione semplificata. Ma ciò significa anche che non hanno tutte le abilità. Implementare metodi di estensione, che possono mantenere lo stato locale su una base di "sé" (fondamentalmente cosa farebbero i campi/le proprietà) è effettivamente difficile da fare in modo efficiente ... ma si possono sempre usare le meta class per istanza per questo.

0

Per tutti gli scopi estesi sono zucchero sintattico in modo che un metodo statico sembra essere più simile a OOP. Non esiste un'eredità perché i metodi statici in Java e Groovy non partecipano all'ereditarietà (ovvero le classi non ereditano metodi statici).

I metodi devono essere statici perché il compilatore non sa come creare un'istanza della classe circostante del metodo di estensione.

Tuttavia, credo che esistano linguaggi che consentono di definire i metodi al di fuori della classe di inclusione e di eseguire una sorta di ereditarietà, ma non molti (credo che CLOS e Dylan lo facciano). Inoltre sono molte lingue che sembrano consentire l'aggiunta di metodi, ma il tipo di "oggetto" è effettivamente cambiato/nascosto ad un altro tipo. Questo è chiamato polimorfismo ad hoc (ad esempio Clojure, Haskell, una sorta di Golang e una sorta di Scala) ma ancora non ha nulla a che fare con il polimorfismo inclusivo (ereditarietà di Java).

0

Purtroppo la reference documentation e altri documenti non definiscono la semantica di metodi di estensione:

  • Q. Possono eseguire l'override metodi di istanza?
    Ho provato i metodi di estensione tramite metodi use e metodi di expando metaClass. Nessuno dei due metodi sovrascrive i metodi di istanza. Non ho provato extension modules installato tramite module descriptor.
  • D. Possono essere sovrascritti dai metodi di estensione nelle sottoclassi?
    Ho provato anche quello. I metodi use e i metodi di estensione metaClass non vengono sovrascritti dai metodi di estensione nelle sottoclassi.
  • D. Possono chiamare i metodi ereditati super?
    No, poiché sono implementati tramite i metodi static.
  • D. Possono chiamare metodi privati?
    Gli esperimenti hanno dimostrato che possono, sorprendentemente.
  • D. Possono accedere a variabili di istanza private?
    No, poiché sono implementati tramite i metodi static.
  • D. Sono richiamabili dai metodi Java?
    Forse, if the extension module is on the classpath durante la compilazione del codice chiamante. Non l'ho provato

Conclusione:metodi di estensione non sono una forma di ereditarietà. Sembrano essere una forma dinamica di Universal Function Call Syntax (UFCS), ovvero, quando la lingua non riesce a trovare un metodo variable.foo(arguments), cerca una funzione di estensione statica foo(variable, arguments) da chiamare. [Si prega di correggere la mia ipotesi se errata!]

Hai chiesto perché sono definiti come static. Ciò sembra corrispondere alla semantica: una funzione statica che non è coinvolta nell'ereditarietà, anche se la sua sintassi di chiamata lo fa sembrare una comoda chiamata al metodo.

È possibile scrivere un metodo di estensione come un metodo di istanza utilizzando l'annotazione @groovy.lang.Category. Trasforma AST in fase di compilazione per trasformarlo in un metodo statico adatto.

Vedere anche Groovy traits. Che è una forma di ereditarietà (mixin).

Problemi correlati