Beh, sì, è corretto.
Quando si definisce tratto Foo
, sarà sotto il cofano creare sia (JVM) Interfaccia Foo
e (JVM) classe Foo$class
con tutte le implementazioni dei metodi definiti come metodi statici. Il codice Java corrispondente sarebbe simile a qualcosa di simile (per la nuova definizione a di Foo
):
interface Foo {
Option<String> verifyConsistency();
}
class Foo$class {
static Option<String> verifyConsistency(Foo self) {
Predef.???();
}
}
Quando si mescolano Foo
in una classe concreta Bar
, ciò che accade a livello di JVM è che Bar
estende l'interfaccia Foo
, e implementa il metodo verifyConsistency
inoltrando semplicemente la chiamata a Foo$class
:
class Bar implements Foo {
Option<String> verifyConsistency() {
return Foo$class.verifyConsistency(this); // simple forwarding
}
}
il motivo per cui lo si fa in questo modo è che il modello a oggetti JVM non supporta l'ereditarietà multipla. Le implementazioni dei tratti non possono essere semplicemente inserite in classi da cui potresti estendere, perché puoi sempre estendere una sola classe sulla JVM.
Il take away di questa situazione è che ogni volta che una classe concreta mescola un tratto, la classe definisce i metodi "stub" per ogni membro del tratto (quei metodi semplicemente inoltrano l'implementazione effettiva, che è un metodo statico).
Una conseguenza è che se si aggiunge un nuovo metodo a un tratto, anche se si definisce un'implementazione non è sufficiente: le classi concrete che mescolano il tratto devono essere ricompilate (in modo che venga aggiunto uno stub per il nuovo metodo alla classe). Se non ricompilate quelle classi, il vostro programma non riuscirà a funzionare, poiché ora avreste una classe che è presumibilmente concreta (non astratta) E estenderete l'interfaccia corrispondente, ma in realtà mancherete l'implementazione per il nuovo metodo.
Nel tuo caso questo significa avere classi concrete che estendono l'interfaccia Foo
ma non hanno alcuna implementazione per verifyConsistency
.
Quindi l'incompatibilità binaria.
fonte
2013-08-21 23:53:06
Ok, grazie. Ho pensato che l'intera cerimonia attorno ai tratti era che si potevano aggiungere metodi e, a patto di fornire un'implementazione predefinita, non si deve ricompilare tutto. Quindi immagino di essermi sbagliato :-( –