Domanda

Ottengo diversi oggetti di tipo Pippo da una chiamata a un'API esterna.A livello locale voglio elaborare quegli oggetti con alcune informazioni aggiunte, quindi ho una sottoclasse FooSon che aggiunge quei campi extra.Come posso convertire tutti gli oggetti che ottengo nel mio nuovo tipo ereditato?Il downcasting non sembra essere un'opzione perché quegli oggetti non lo sono realmente FooSon.

L'unica soluzione che ho trovato è creare una funzione di conversione che accetta il file Pippo object come argomento e quindi copia tutti i valori pubblici/protetti in uno nuovo FooSon oggetto che viene poi restituito.

Gli svantaggi sono:

  • Perdita di informazioni (valori privati)
  • Dover adattare la funzione di conversione if Pippo è mai cambiato.

La classe Foo non implementa un costruttore di copia o un operatore clone.Ho il codice sorgente di Foo ma vorrei evitare di modificarlo per mantenere la compatibilità con le versioni future.Tuttavia, se è l'unica alternativa praticabile, cambierei l'implementazione di Foo per ottenere ciò di cui ho bisogno.

È stato utile?

Soluzione

Fooson potrebbe avere un campo che è un foo. Quindi basta assegnare il valore restituito in quel campo. Potresti quindi creare metodi in Fooson che delegano le loro chiamate al campo Foo per le informazioni di cui hai bisogno dal foo dall'esterno.

Altri suggerimenti

Penso che il motivo decoratore dovrebbe funzionare qui:

class Foo implements FooApi {...}

class FooSon implements FooApi {
    private FooApi decoratedFoo;
    private String additional;

    public FooSon(FooApi decoratedFoo) {
        this.decoratedFoo = decoratedFoo;
    }
    ...
}

Ma puoi farlo solo se hai un'interfaccia per il tuo oggetto Foo.

Forse non ho compreso appieno il problema, ma perché invece di sottoclassare Foo (ereditarietà) non memorizzi Foo come un tipo di campo in FooSon (composizione)?

In ogni caso, se non è possibile modificare il controllo di accesso sul tipo Foo perché gli oggetti sono definiti in una libreria esterna, non è possibile ottenere l'accesso diretto ai campi privati ​​(questa è esattamente la proprietà di un campo privato).Se è possibile accedere a questi campi privati ​​dal metodo getter e setter, racchiudi tali metodi nella classe FooSon.

Bene, come hai già scoperto il casting non è applicabile in questa situazione. Vedo le seguenti opzioni:

  • La libreria esterna fornisce alcuni meccanismi di fabbrica che potresti utilizzare per renderlo istanziato FooSon invece Foo.

  • Il destinatario avvolge Foo oggetti in FooSon Oggetti, possibilmente usando il modello del delegatore.

  • Il destinatario allega logicamente ulteriori informazioni a Foo oggetti usando una mappa con Foo come chiave.

Non dovresti abbattere, non hai alcuna garanzia che avrà successo e ci sono modi migliori per affrontare questo problema. Per uno è possibile avvolgere l'oggetto Foo in un'altra classe e delegare il metodo appropriato richiamati all'oggetto Foo.

Ti suggerisco di prenderti un po 'di tempo per assicurarti di capire alcuni concetti OO di base. In particolare, Google per "composizione contro eredità", questo collegamento Sembra una spiegazione decente.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top