Utilizzando sottoclasse di sostituire una classe Java che non implementa un'interfaccia
Domanda
Per esempio, java.io.File è solo una classe concreta. Il mio sostituto per esso supporta la risoluzione collegamenti di Windows. Ho bisogno di parametri del costruttore pre-elaborazione per risolvere eventuali file .lnk perché l'oggetto FileSystem che fa normalizzante / canonicalision / risolvere sui sentieri astratti non è accessibile. La necessità di pre-elaborazione esclude sottoclasse pura - non si può fare di pre-elaborazione prima di chiamare super (...) e del file è immutabile. Così va il file e utilizzare un delegato, ignorando tutti i costruttori ei metodi di file (chiamare super ( "") in tutti i costruttori).
Questo funziona bene, ma non è ovviamente l'ideale - se le modifiche del file, io non ho sovrascritto eventuali nuovi metodi o costruttori e questo sarà esporre il sottostante percorso astratto vuoto. Mi sto perdendo qualcosa di ovvio? Sembra che ci dovrebbe essere un modo più semplice / migliore.
Soluzione
Nel caso specifico si suggeriscono sembra a me come si sta meglio con una classe di fabbrica separato che prende le decisioni circa normalizzante / canonicalision / risolvere.
Poi si può semplicemente lasciare file sia file. Più semplice.
Altri suggerimenti
Se si vuole veramente il percorso sottoclasse, si può imbrogliare il requisito che una chiamata a super()
deve essere la prima linea di un costruttore della sottoclasse posizionando il codice di pulitura al di fuori della classe, o in un blocco statico:
public class MyFile extends File {
public MyFile(String path) {
// static blocks aren't ideal, this is just for demo purposes:
super(cleanPath(path));
}
private static String cleanPath(String uncleanPath) {...}
}
Il modello di fabbrica suggerito da krosenvold è un'altra buona soluzione.
Questo funziona bene, ma non è ovviamente l'ideale - se le modifiche del file, io non ho sovrascritto eventuali nuovi metodi o costruttori e questo sarà esporre il sottostante percorso astratto vuoto. Mi sto perdendo qualcosa di ovvio?
No, hai trovato un problema con l'utilizzo di successione - che le sottoclassi vengono strettamente accoppiati alle superclassi e le loro interni, in modo che possa essere fragile. Questo è il motivo Effective Java e altri dicono che si dovrebbe favorire la delega prima di eredità, se possibile.
Credo che la soluzione di krosenvold suoni puliti.
Mi sembra che la soluzione di krosenvold è la strada da percorrere.
Ma, se avete bisogno di tenere traccia del percorso originale che ha creato il file, è possibile implementare una classe wrapper.
public class FileWrapper {
private File file;
private String path;
private FileWrapper(String path) {
this.path = path;
file = new File(preProcess(path));
}
private String preProcess(String path) {
// process
return path;
}
public File getFile() {
return file;
}
public String getPath() {
return path;
}
}