2011-08-19 6 views
8

Ho una sottoclasse che deve restituire una sottoclasse del tipo restituito della sua classe genitore. Credo che questo sia chiamato un tipo di ritorno covariante. Mi sto chiedendo il modo più semplice per convertire dalla classe padre alla classe figlio.Qual è il modo OO corretto per convertire un oggetto in una delle sue sottoclassi (tipo di ritorno covariante)?

class A { 
} 
class B extends A { 
    function bar() { 
    } 
} 

class Car { 
    function foo() { 
    return new A(); 
    } 
} 

class BrokenCar extends Car { 
    function foo() { 
    $a = parent::foo(); 
    //What is the cleanest way to convert $a to type B ? 
    } 
} 

risposta

8

In PHP non si può "convertire" gli oggetti dal tipo/classe A a B con una funzione disponibile nella lingua.

È possibile farlo utilizzando la serializzazione se gli oggetti lo supportano (normalmente gli oggetti PHP vecchi supportano la serializzazione). Nella forma serailizzata si modifica la classe dell'oggetto e lo si riscrivono nuovamente. A è diventato poi B. Ma non è molto fluente.

2

Questo in realtà dovrebbe essere un commento, ma ho intenzione di fare un punto importante.

La programmazione è ingegneria e la programmazione è progettazione. Non c'è modo di dire perché il design A è migliore del design B senza sapere come verrà usato. Chiedi a un designer, se il tuo pulsante di invio è rosso o verde - e lei dice: hmm, dove, su quale sito? Chiedi a un ingegnere se dovresti usare una trave o una leva del cambio - e la risposta sarà: dipende da che cosa. Quindi, cosa ti fa pensare che possiamo darti un significativo consiglio di design, se solo ci fornisci una lezione "BrokenCar" con un metodo "foo". Dicci cosa realmente vuole raggiungere con questo, altrimenti l'unica risposta che può venire in mente è

il modo migliore per utilizzare foo è il bar

+1

Scusate per l'esempio vago ... Ho cercato di semplificare quello che stavo facendo forse troppo. Intendevo illustrare che "B" fornisce metodi extra che non esistono in "A". 'B' sovrascrive anche alcuni metodi da 'A' nel mio codice attuale. Potrei duplicare la logica nei metodi sovrascritti e quindi chiudere semplicemente chiamando il metodo "pippo" padre, ma questa è stata un'enorme duplicazione. –

2

Come hakre dichiarato, lanciando ai tipi definiti dall'utente non è nativamente possibile in PHP (per quanto ne so).

Che cosa si potrebbe fare è creare un metodo sia in classe A o B. Qualcosa di simile:

class A 
{ 
    public static function fromB(B $object) 
    { 
     /* your routine to convert an object of class B to an instance of class A */ 
    } 

    /* or */ 

    public static function fromA(A $object) 
    { 
     /* your routine to convert any object that is a subclass of A to a concrete instance of class A */ 
    } 
} 

o

class B 
    extends A 
{ 
    // this method could even be implemented in A already as well actually 
    public function toA() 
    { 
     /* your routine to convert this object to an object of class A */ 
    } 
} 

Nel primo esempio la prima factory method può essere problematico, dal momento che richiede A di avere conoscenze concrete su una sottoclasse specifica. Hai bisogno di determinare se questo è desiderabile nella tua situazione. Forse potresti astrarre questo per avere il metodo factory accettare qualsiasi oggetto che eredita da A, come il secondo metodo factory.

Nel secondo esempio, B conosce già automaticamente A, poiché ne eredita. Questo potrebbe essere più desiderabile. Ma a pensarci bene, questo potrebbe anche essere già implementato in A, così che il metodo sia già disponibile automaticamente in tutte le sottoclassi di A.

Problemi correlati