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 :

  1. E 'il modo corretto per chiamare la funzione dalla classe base (((MyBase)myDerived).MyMethod();)? So di base parola chiave, ma può essere chiamato solo dall'interno della classe derivata. E 'giusto?
  2. Perché in quest'ultimo caso (con virtual e override modificatori) il metodo che è stato chiamato è venuto dalla classe derivata? La prego quindi di spiegare che?
È stato utile?

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.

  1. Hai ragione, base si riferisce alla classe di base per una determinata istanza.
  2. 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.

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