C # Nascondere, ignorando e funzione di chiamata dalla classe di base
-
21-09-2019 - |
Domanda
Sto imparando C # e ho incontrato il seguente problema. Ho due classi: base e derivati:
class MyBase
{
public void MyMethod()
{
Console.WriteLine("MyBase::MyMethod()");
}
}
class MyDerived: MyBase
{
public void MyMethod()
{
Console.WriteLine("MyDerived::MyMethod()");
}
}
Per il momento, senza virtual
e override
parole chiave. Quando compilo questo ottengo l'avvertimento (che è ovviamente previsto) che cerco di nascondere MyMethod
dalla classe MyBase
.
Quello che voglio fare è quello di chiamare il metodo della classe base con un'istanza della classe derivata. Lo faccio in questo modo:
MyDerived myDerived = new MyDerived();
((MyBase)myDerived).MyMethod();
Funziona bene quando non specifica alcun virtual
, ecc parole chiave nei metodi. Ho provato a mettere insieme delle parole chiave e ho ottenuto i seguenti risultati:
| MyBase::MyMethod | MyDerived::MyMethod | Result printed on the console |
| -----------------|---------------------|-------------------------------|
| - | - | MyBase::MyMethod() |
| - | new | MyBase::MyMethod() |
| virtual | new | MyBase::MyMethod() |
| virtual | override | MyDerived::MyMethod() |
Spero che il tavolo è chiaro a voi. Ho due domande :
- E 'il modo corretto per chiamare la funzione dalla classe base (
((MyBase)myDerived).MyMethod();
)? So dibase
parola chiave, ma può essere chiamato solo dall'interno della classe derivata. E 'giusto? - Perché in quest'ultimo caso (con
virtual
eoverride
modificatori) il metodo che è stato chiamato è venuto dalla classe derivata? La prego quindi di spiegare che?
Soluzione
Quando si chiama un metodo virtual
su un'istanza di un tipo che l'override del metodo, sarà sempre chiamato la versione override, anche se si esegue il cast alla classe di base.
L'unico modo per chiamare l'implementazione di base di un metodo virtuale in una classe che sostituisce il metodo è quello di realizzare un secondo metodo nella classe derivata (non la classe base) che chiama il metodo che utilizza la parola base
.
In generale, la necessità di fare questo è un segno di una cattiva progettazione API -. Se si pensa sarà necessario chiamare la versione base, la versione derivata dovrebbe probabilmente avere un nome diverso
Altri suggerimenti
Per quanto riguarda la seconda domanda, non si è cambiando il tipo di oggetto si dispone di un riferimento, solo l'interfaccia si fa riferimento attraverso. Quindi, se si dispone di un oggetto B che eredita da A e l'override di funzione C, anche se si fa riferimento a B come una A, si chiama ancora le implementazioni del tipo più derivato, in questo caso B.
Hai ragione - base
può essere chiamato solo dall'interno della classe derivata - Fonte .
Questa pagina fornisce anche un esempio di come eseguire l'override la definizione della classe di base.
- Hai ragione,
base
si riferisce alla classe di base per una determinata istanza. - Il meccanismo coinvolto è chiamato polimorfismo: si dovrebbe meglio lavorare senza preavviso. L'oggetto naturale orientata buon modo è l'ultimo dei casi che hai citato.
Tra l'altro, cercare di evitare la scrittura di codice che applica il principio di sostituzione, in altre parole, non scrivere codice che dipende dall'implementazione della gerarchia di classe perché dovrete modificare questo codice se si aggiunge un nuovo classe derivata alla classe di base.