È un po 'oscuro, ma la mia ipotesi istruita (perché nessuna altra ipotesi sembra avere un senso) è che:
- Per "ereditarietà per il riutilizzo [del codice] esterno" si intendono i casi in cui un sottosistema espone (rende disponibile al pubblico) una classe base astratta, che deve essere estesa da altre classi di questo sottosistema o di altri sottosistemi. Quindi, in sostanza, il codice che usa la classe base è a conoscenza del fatto che l'ereditarietà è utilizzata.
Esempio:
public abstract class A {};
/* package-private or public */ class B extends A {};
/* package-private or public */ class C extends A {};
- Per "ereditarietà per riutilizzo interno [codice]" si intendono i casi in cui un sottosistema espone (rende disponibile al pubblico) un'interfaccia, implementata internamente da un certo numero di classi che non sono esposte pubblicamente, e al fine di ottenere il riutilizzo del codice, il sottosistema utilizza una classe di base comune a pacchetto anche privata per tutte le classi di implementazione. Ma nessuna di queste classi è esposta pubblicamente, quindi il codice al di fuori del pacchetto non è a conoscenza del fatto che le implementazioni dell'interfaccia stanno estendendo qualche classe base comune.
Esempio:
public interface I {};
/* package-private */ abstract class A implements I {};
/* package-private */ class B extends A {};
/* package-private */ class C extends A {};
Naturalmente, il riutilizzo interno è il migliore, perché consente la massima flessibilità: il sottosistema si nasconde dal mondo esterno perché internamente utilizza l'ereditarietà, quindi il sottosistema può essere successivamente refactored per utilizzare la composizione anziché l'ereditarietà, e il mondo esterno non se ne accorgerà. (Il codice esterno non dovrà nemmeno essere ricompilato.) In sostanza, quando l'ereditarietà viene utilizzata per il riutilizzo del codice interno, la classe base comune non è altro che un helper.