Se si dispone di più classi in cui si desidera che ereditino da una classe base per funzionalità comuni, è necessario implementare la classe base utilizzando una classe o una classe astratta?Eredita da una classe o una classe astratta
risposta
Dipende, se non si desidera essere in grado di creare un'istanza della classe base, quindi renderla astratta. Altrimenti lasciala come una classe normale.
Direi che se non hai intenzione di chiamare la classe base da sola, allora dovresti definirla come una classe astratta.
Direi che non è abbastanza - dovresti dichiarare un estratto di classe solo se non ha senso istanziarlo direttamente. Che tu lo pianifichi o meno è un problema completamente diverso. –
Dipende dal fatto se si desidera che la classe base sia implementata da sola oppure no.
Come classe astratta, non è possibile creare oggetti da esso.
Dipende, ha senso che la classe base in questione esista da sola senza essere derivata? Se la risposta è sì, allora dovrebbe essere una classe normale, altrimenti dovrebbe essere una classe astratta.
Se la classe base non deve essere istanziata, rendila una classe astratta - se la classe base ha bisogno di essere istanziata, allora non renderla astratta.
In questo esempio ha senso per rendere la classe di base astratta come classe base non ha alcun significato concreto:
abstract class WritingImplement
{
public abstract void Write();
}
class Pencil : WritingImplement
{
public override void Write() { }
}
Tuttavia, in questo esempio successivo si può vedere come la classe di base ha significato concreto :
class Dog
{
public virtual void Bark() { }
}
class GoldenRetriever : Dog
{
public override void Bark() { }
}
E 'tutto abbastanza soggettivo davvero - si dovrebbe essere in grado di fare un buon chiamata in giudizio in base alle esigenze della vostra particolare dominio.
Le classi astratte sono ideali per funzionalità predefinite, ad esempio, quando si conosce il comportamento esatto minimo che una classe dovrebbe esporre ma non i dati che dovrebbe utilizzare per farlo o l'esatta implementazione.
abstract class ADataAccess
{
abstract public void Save();
}
normali (abstract) non classi possono essere grande per cose simili, ma è necessario conoscere le specifiche di implementazione per essere in grado di scrivere di loro.
public class DataAccess
{
public void Save()
{
if (_is_new)
{
Insert();
}
else if (_is_modified)
{
Update();
}
}
}
Inoltre, è possibile utilizzare le interfacce (singolarmente o in classi, sia astratta o meno) per definire lo stesso tipo di definizione del prototipo.
interface ISaveable
{
void Save();
void Insert();
void Update();
}
class UserAccount : ISavable
{
void ISavable.Save() { ... }
void ISavable.Insert() { ... }
void ISavable.Update() { ... }
}
Ancora un'altra opzione possono fare uso di farmaci generici
class GenDataAccess<T>
{
public void Save()
{
...
}
}
Tutti questi metodi possono essere utilizzati per definire un certo prototipo per le classi con cui lavorare. Modi per assicurarsi che il codice A possa parlare con il codice B. E ovviamente puoi combinare tutto quanto sopra a tuo piacimento. Non esiste un modo preciso ma mi piace definire interfacce e classi astratte, quindi fare riferimento alle interfacce. In questo modo si eliminano alcuni dei requisiti di pensiero per "tubature" nelle classi di livello superiore pur mantenendo la massima flessibilità. (avendo interfacce toglie il requisito di utilizzare la classe di base astratta, ma lascia come opzione).
Le classi astratte sono per classi parzialmente implementate.
Di per sé non ha senso avere un'istanza di una classe astratta, deve essere derivata. Se vuoi essere in grado di creare la classe base, non può essere astratta.
Mi piace pensare alle classi astratte come interfacce che hanno alcuni membri predefiniti poiché sono comuni a tutte le sottoclassi.
Pensate a questo modo diverso
La mia una classe base di un oggetto completo su di essa la propria?
Se la risposta è no, quindi renderla astratta. Se è sì, probabilmente vorrai renderlo un corso concreto.
suggerisco:
- Fai interfaccia.
- Implementare l'interfaccia nella classe base.
- Rendi la classe base una vera classe, non astratta (vedi sotto per il perché).
La ragione per cui io preferisco le classi reali, invece di classi astratte è che le classi astratte non possono essere istanziati, che limita le opzioni future inutilmente. Per esempio, più avanti potrei aver bisogno dello stato e dei metodi forniti dalla classe base ma non posso ereditare e non ho bisogno di implementare l'interfaccia; se la classe base è astratta, sono sfortunato, ma se la classe base è una classe regolare, allora posso creare un'istanza della classe base e tenerla come un componente della mia altra classe, e delegare all'istanza per riutilizzare la classe stato/metodi forniti.
Sì, questo non accade spesso, ma il punto è: rendere l'abstract della classe base impedisce questo tipo di riutilizzo/soluzione, quando non vi è alcun motivo per farlo.
Ora, se istanziare la classe di base avrebbe in qualche modo essere pericoloso, quindi renderlo astratto - o, preferibilmente, renderlo meno pericoloso, se possibile ;-)
Pensate a come un conto in banca:
È può creare un account di base astratto generico chiamato "Account", che contiene informazioni di base come i dettagli del cliente.
È quindi possibile creare due classi derivate denominate "SavingAccount" o "DebitAccount" che possono avere il proprio comportamento specifico beneficiando del comportamento della classe base.
Questa è una situazione in cui il cliente deve avere un Conto di risparmio o un Conto di addebito, un "Conto" generico non è consentito in quanto non è molto popolare nel mondo reale per avere solo un account di nessuna descrizione.
Se è possibile creare uno scenario simile per le proprie esigenze, l'abstract è la strada da percorrere.
Penso che molti di voi dovrebbero nuovamente eseguire di nuovo le classi OO di base.
Il principio base di base in OOA/OOD è quello di astrarre astratto astratto, fino a quando non è possibile non più astratto. Se ciò che stai guardando è un'astrazione, così sia, questo è ciò che il tuo OOA/OOD già ti ha detto.Tuttavia, se sei seduto lì a chiedermi se il "codice" debba essere astratto o no, ovviamente non sai cosa significhi il termine e dovresti imparare di nuovo OOA/OOD/OOP di base :-)
Più che al punto che dovresti impara i modelli di design e la teoria armonica, questo aiuterà enormemente i tuoi disegni OO!
Posso dirti che stai leggendo molto. Spendi un po 'di quella energia invece di imparare a scrivere senza essere offensivo. –
Esatto, se non ha senso istanziare la classe base, renderla astratta. – mbillard