L'override di un metodo influisce sulla chiamata di una superclasse?

1

Sto cercando di capire alcune delle sfumature dell'ereditarietà ma non riesco a trovare una risposta a questa domanda. Considera quanto segue:

class SuperClass {
    method foo {
        print "in SuperClass.foo"
    }
    method bar {
        print "in SuperClass.bar"
        foo();
    }
}
class SubClass inherits SuperClass {
    method foo {
        print "in SubClass.foo"
    }
}

SubClass a = SubClass.new()
a.bar()

L'output è questo:

in SuperClass.bar
in SuperClass.foo

O questo:

in SuperClass.bar
in SubClass.foo
    
posta shawnhcorey 01.01.2015 - 17:22
fonte

3 risposte

8

Dipende dalla lingua che stai usando (e talvolta da come sono dichiarati i metodi).

Ci sono essenzialmente due modi per l'implementazione di eseguire chiamate di metodo: invio statico e invio dinamico.

In dispatch statico , il compilatore determina esattamente al momento della compilazione quale metodo chiamare, senza prendere in considerazione la possibilità che possa esistere una sottoclasse che sovrascrive il metodo.
Con l'invio statico, l'output sarebbe

In SuperClass.bar
In SuperClass.foo

In dispatch dinamico , il compilatore fa prende in considerazione che una sottoclasse potrebbe sovrascrivere il metodo, quindi imposta cosa che l'ambiente runtime può chiamare metodo giusto nella super classe o nella sottoclasse.
Con l'invio dinamico, l'output sarebbe

In SuperClass.bar
In SubClass.foo

Quale metodo di invio viene usato dipende dalla lingua che si usa, da come sono dichiarati i metodi e da come si esegue la chiamata.
In C ++ e C #, il compilatore utilizza l'invio statico per impostazione predefinita, a meno che il metodo non sia stato dichiarato come virtual .
In Java, il compilatore utilizza l'invio dinamico per impostazione predefinita.

    
risposta data 01.01.2015 - 17:46
fonte
4

Anche quando la chiamata al metodo ha origine nella superclasse, dovrebbe chiamare il metodo di override nella sottoclasse. Questo comportamento è talvolta chiamato "ricorsione aperta" e questa caratteristica è cruciale per tecniche come il "modello di strategia". La ricorsione aperta è generalmente considerata un concetto fondamentale di programmazione orientata agli oggetti, sebbene non sia senza problemi.

Ci sono alcuni avvertimenti in quanto alcune lingue aggiungono requisiti speciali.

  • In alcune lingue, devi sempre invocare metodi con la notazione a punti perché funzioni. Dovresti dire this.foo() anziché solo foo() .

  • Alcune lingue richiedono di contrassegnare esplicitamente i metodi come sovrascrivibili. Per esempio. C ++ richiederebbe che il metodo foo venga contrassegnato come virtual affinché funzioni come previsto. Nella maggior parte delle lingue, i metodi possono essere sovrascritti per impostazione predefinita.

risposta data 01.01.2015 - 17:42
fonte
1

Dipende. In alcune lingue, la superclasse foo () verrebbe chiamata di default, ma esiste un modo per dichiarare che si desidera richiamare la versione della sottoclasse (in c ++ e c # si usa la parola chiave "virtuale" nella dichiarazione di superclasse. foo () per ottenere ciò). In altri (ad esempio Java e i linguaggi più dinamici come ruby, python e così via) viene sempre utilizzata la versione sottoclasse.

    
risposta data 01.01.2015 - 17:42
fonte

Leggi altre domande sui tag