2010-07-14 12 views

risposta

16

Dichiarando un metodo come virtual, sei indicando la tua intenzione che il metodo può essere ignorato in una classe derivata.

Dichiarando il tuo metodo di esecuzione in quanto override, il vostro sono indicando la vostra intenzione questo modo si sostituisce un metodo virtual.

Richiedendo l'utilizzo della parola chiave override per sovrascrivere un metodo virtuale, i progettisti del linguaggio incoraggiano la chiarezza, richiedendo di indicare le proprie intenzioni.

+0

Perché non contrassegnarlo come 'astratto' e forzare l'override? –

+1

@George: perché puoi usare il modificatore astratto solo nelle classi astratte. –

+3

@George Stocker - Perché potresti non voler contrassegnare l'intera classe come astratta (la classe ha bisogno del modificatore astratto per avere metodi astratti). –

5

Perché rende il codice più leggibile:

class Derived : Base 
{ 
    void Foo(); 
} 

In C++, Foo può o non può essere un metodo virtuale, non possiamo dire guardando la definizione. In C# sappiamo che un metodo è virtuale (o non lo è) perché c'è una parola chiave virtuale o override.

Il commento di Jason di seguito è una risposta migliore.

(a cura per chiarezza)

+1

... e offre ad Intellisense la possibilità di aiutarci a scavalcare un metodo. Digita "override" e Intellisense si apre con una scelta e riempie persino l'intera firma del metodo per noi. Quanto è fantastico? – Tergiver

+5

... e, cosa più importante, permette al compilatore di dirci quando commettiamo un errore (ad esempio se aggiungi un parametro al metodo della classe base in C++, interrompe tutte le classi derivate ma non hai modo di conoscerlo - una causa di alcuni bug davvero maliziosi, perché i bit del comportamento della classe derivata smettono di funzionare in silenzio. In C# restituisce un errore per ogni override che non sovrascrive più nulla) –

+0

_ "In C++ potrebbe essere, possiamo ' t dire guardando la definizione. "_ - Osservando la definizione, possiamo dire che non è affatto C++. – stakx

11

Se non si aggiunge la parola chiave override, il metodo verrà nascosto (come se fosse la parola chiave new), non sovrascritto.

Ad esempio:

class Base { 
    public virtual void T() { Console.WriteLine("Base"); } 
} 
class Derived : Base { 
    public void T() { Console.WriteLine("Derived"); } 
} 

Base d = new Derived(); 
d.T(); 

Questo codice stampe Base. Se si aggiunge override all'implementazione Derived, il codice verrà stampato Derived.

Non è possibile farlo in C++ con un metodo virtuale. (There is no way to hide a C++ virtual method without overriding it)

+0

Perché così tante persone non sanno del comportamento predefinito 'new' ... – Dykam

+1

Sono d'accordo che questo non dovrebbe essere legale e dovrebbe lanciare un Errore invece di un Avvertimento. (Modifica: qualcuno ha rimosso il suo commento sopra questo). – Dykam

+0

Warings come errori FTW! –

1

Non tutti i metodi virtuali devono essere sovrascritti, sebbene tutti i metodi astratti debbano (e debbano) essere. Per quanto riguarda il motivo per cui la parola chiave 'override' è esplicita, perché override e hiding si comportano diversamente. Un metodo di nascondimento non viene chiamato attraverso un riferimento a una classe base, mentre è un metodo sovrascritto. Questo è il motivo per cui il compilatore avverte in modo specifico su come dovresti usare la "nuova" parola chiave nel caso in cui ti stai nascondendo piuttosto che sovrascrivere.

10

È perché i membri del team C# sono tutti programmatori C++ qualificati. E sa come incipiente questo particolare bug è:

class Base { 
protected: 
    virtual void Mumble(int arg) {} 
}; 

class Derived : public Base { 
protected: 
    // Override base class method 
    void Mumble(long arg) {} 
}; 

è molto più comune, allora si potrebbe pensare. La classe derivata viene sempre dichiarata in un altro file di codice sorgente. Normalmente non si sbaglia subito, succede quando si refactoring. Nessun peep dal compilatore, il codice funziona abbastanza normalmente, semplicemente non fa quello che ti aspetti che faccia. Puoi guardarlo per un'ora o un giorno e non vedere il bug.

Questo non può mai accadere in un programma C#. Anche il C++ gestito ha adottato questa sintassi, rompendo intenzionalmente la sintassi C++ nativa. Sempre una scelta coraggiosa IntelliSense elimina la verbosità in più.

C'è un sacco di modifiche alla sintassi in C# che assomigliano a questo tipo di sintassi per evitare errori.


EDIT: e il resto della comunità di C++ ha accettato e ha adottato il di override parola chiave nella nuova specifica del linguaggio C++ 11.

+1

+1 Risposta migliore IMO perché spiega il "perché" alla base della decisione sulla progettazione della lingua anziché "come funzionano le chiamate virtuali" in quanto le risposte con rating più elevato fanno ... PS. @Hans Sembra che tu stia sbattendo un sacco di risposte pertinenti da te scritte in questi giorni :) –

0

Non è necessario sovrascrivere esplicitamente un metodo virtuale in una classe derivata. Contrassegnare un metodo virtuale consente solo l'override.

Problemi correlati