[OO] come ereditare solo parte di un metodo o proprietà di un oggetto?

E' difficile mettere come oggetto del post la questione, spero che renda l'idea, comunque veniamo al punto.

Finalmente mi dedico un po' più seriamente agli oggetti e mi trovo di fronte ad un dubbione.

Ho 2 oggetti fornitori e clienti, nello specifico clienti estende fornitori perchè ha delle proprietà e dei metodi in più, quindi le due classi sono così per ora (ancora non le uso):

Fornitori:

class fornitore {
protected $codice;
protected $denominazione;
protected $indirizzo;
protected $cap;
protected $citta;
protected $prov;
protected $pi;
protected $cf;
protected $tel;
protected $fax;
protected $contatto;
protected $note;
private $tabella="fornitori";

      function __construct($codice,$dati=NULL){
               if (!is_null($dati)) {
                  $this->codice = $this->addNew($dati);
               }
               else {
                    $this->codice = $codice;
               }
      }
      function getCode(){
               return $this->codice;
      }
      function addNew($dati){
               return "nuovo";
      }
};

le proprietà sono protected perchè non devono essere accessibili all'esterno, ma devono essere ereditate, il nome della tabella invece non deve essere ereditato da altre classi, forse lo trasformerò in costante (ma non è questo il punto).

Clienti:

require ("class.fornitore.php");

class cliente extends fornitore{
protected $banca;
protected $pagamenti;
private $tabella="clienti";

};

Quindi cliente eredita tutte le funzioni di fornitore e poi aggiungerò quelle specifiche, ma il punto è il metodo addNew(), la tabella dei clienti prevede più campi rispetto a quella dei fornitori e non vorrei riscrivere la funzione, come rendere solo la query di inserimento di questa funzione non ereditabile senza farne una proprietà dell'oggetto?

Edit:

Ovviamente il problema si pone anche per l'update!

inviato 9 anni fa
LonelyWolf
modificato 9 anni fa
X 0 X

Un'idea malsana mi giunge alla mente: come ottengo l'elenco dei capi di una tabella? Non lo ricordo proprio.

risposto 9 anni fa
LonelyWolf
X 0 X

Ok, ho risolto grazie lo stesso, a volte parlare con qualcuno aiuta.

risposto 9 anni fa
LonelyWolf
X 0 X
Un'idea malsana mi giunge alla mente: come ottengo l'elenco dei capi di una tabella? Non lo ricordo proprio.

cosa sono i capi di una tabella?

Ok, ho risolto grazie lo stesso, a volte parlare con qualcuno aiuta.

Che approccio stai utilizzando?

 :bye:

risposto 9 anni fa
Gianni Tomasicchio
X 0 X

i capi di una tabella? penso che siano l'inizio e la fine, io però intendevo i campi! :D errore di battitura.

Alla fine recupero l'elenco dei campi e costruisco la query, così devo solo accertarmi che il numero dei dati da inserire sia uguale al numero dei campi della tabella e soprattutto non devo aggiungere o togliere niente tra "genitore" e "figlio"!

risposto 9 anni fa
LonelyWolf
X 0 X

Ti segnalo questo progetto:

http://propel.phpdb.org/trac/

 :bye:

P.S.: ti faccio notare il corretto approccio alla cancellazione di un record, che non passa per un metodo dell'oggetto ma per un metodo statico della classe:

http://propel.phpdb.org/trac/wiki/Users/Documentation/1.2/BasicCRUD (alla fine della pagina)

risposto 9 anni fa
Gianni Tomasicchio
modificato 9 anni fa
X 0 X

Ti ringrazio, ho visto che il delete lo fa esattamente come nel mio caso, usando l'oggetto: prima lo crea/istanzia e poi lo cancella (proprio l'ultimo esempio), comunque ancora tutto è in fase di studio/test quindi faccio, provo, valuto e se necessario cambio!

Stavo invece pensando all'update, mi lascia un po' perplesso.

Ora mi spiego meglio, come vedi dalle mie classi fornitori ha x proprietà e cliente x+2.

Pensavo di fare anche io dei metodi set per ognuna e poi l'update, questo va bene per il fornitore, ma per il cliente? dovrei aggiungere i set per le 2 proprietà in più e riscrivere l'update; ma quello che vorrei fare non prevede questa cosa, essendo l'update una funzione base e cliente figlio di fornitore, come per l'inserimento che è indipendente.

Quindi stavo cercando una soluzione e questo è quello che mi è venuto in mente:

1 - le proprietà le trasformo in un unico array e l'update si costruisce la query come fa l'inserimento

2 - usare un iteratore, che in sostanza non differisce dal metodo precedente, ma mi permette di fare dei set per ogni proprietà senza lavorare con indici di array dentro l'oggetto, nella classe cliente dovrei aggiungere solo quelli per le 2 proprietà in più.

Anche perchè la classe cliente adesso aggiunge solo le due proprietà, ma appena sistemata la classe fornitore dovrà subire un incremento di metodi (lavorare con banche, pagamenti, destinazioni,fatture, preventivi e non ricordo che altro!)

risposto 9 anni fa
LonelyWolf
X 0 X

Mi sembra una buona idea. Comunque rimando dell'opinione che se stai facendo un mapping oggetti<->relazioni, visto che si tratta ormai di una tecnica ormai consolidata, conviene guardare a fondo (ed eventualmente adottare) tecnologie e soluzioni già realizzate.

 :bye:

risposto 9 anni fa
Gianni Tomasicchio
X 0 X

Scusa Gianni ma non capisco cosa intendi per "oggetti<->relazioni".

oggetto<->record nel db mi sembra più appropriato, anche se poi devo aggiungere altre funzionalità.

E' che cerco di scrivere dei metodi nella classe base che non debbano essere riscritti per adattarsi agli oggetti che la estendono.

Infatti l'inserimento lavora in questo modo, la cancellazione, il caricamento.

La funzione getProperty l'avevo fatta di corsa ed era un obrobrio, ma l'ho appena "reinventata" e funzionerà anche per i figli.

Purtroppo per ora usare questa classe significa conoscere il db (i campi e in quale ordine), ma poi ci penseremo.

Adesso la mia classe base permette di:

inserire, cancellare, visualizzare (1 o tutte) le proprietà; per l'update ci devo lavorare un po' ma stanotte mi è venuta un'altra idea:

se facessi un metodo setProperty($proprietà,$valore) che imposta anche una variabile di stato interna in modo che con il "distruttore" venga o meno aggiornato il db?

Che ne dici, potrebbe essere interessante?

risposto 9 anni fa
LonelyWolf
X 0 X

Credo di aver terminato la mia classe base, probabilmente devo ancora aggiungere dei controlli, ma  per ora va bene così.

Ditemi se vi sembra una cosa sensata:

Agisce sulla tabella dei fornitori e permette inserimento, modifica, cancellazione, visualizzazione di una o tutte le proprietà (i valori dei campi).

I metodi disponibili sono solo:

setProperty per impostare una proprietà

getProperty per ottenere una(stringa) o tutte(array) le proprietà

delete per cancellare il record corrispondente dal db.

L'inserimento avviene quando si istanzia l'oggetto nel db, se vengono passati dei dati anzichè solo il codice utilizzando il costruttore della classe.

L'aggiornamento del record nel db avviene quando l'oggetto viene distrutto se sono state fatte delle modifiche utilizzando il distruttore della classe.

I metodi sono stati scritti in modo da funzionare anche con oggetti figli che lavorano su una tabella diversa avente dei campi in più rispetto a quella dei fornitori, ovviamente i nomi dei campi/proprietà della classe base sono identici altrimenti ....nisba! :D

risposto 9 anni fa
LonelyWolf
X 0 X

Io non lascerei il salvataggio dei dati al distruttore ma preferirei una procedura esplicitamente invocata.

 :bye:

risposto 9 anni fa
Gianni Tomasicchio
X 0 X

Se hai tempo dai un'occhiata all'implementazione delle tabelle e dei record fatta nello Zend Framework:

http://framework.zend.com/manual/en/zend.db.table.html

http://framework.zend.com/manual/en/zend.db.table.row.html

P.S.: prima quando ho detto oggetto<->relazione mi stavo riferendo a questo:

http://en.wikipedia.org/wiki/Object-relational_mapping

 :bye:

risposto 9 anni fa
Gianni Tomasicchio
X 0 X
Effettua l'accesso o registrati per rispondere a questa domanda