2010-06-18 21 views
6

Stavo leggendo la documentazione Python su classes e sono imbattuto in questo paragrafo, che io non sono sicuro:Chiamata di metodi sovrascritto nella classe derivata da Base Class

Le classi derivate possono sovrascrivere i metodi delle loro classi base. Poiché i metodi non hanno privilegi speciali quando chiamata altri metodi dello stesso oggetto, un metodo di una classe base che chiama un altro metodo definito nella stessa classe base può finire per chiamare un metodo di una classe derivata che sostituzioni esso. (Per i programmatori C++: tutti i metodi in Python sono effettivamente virtuale.)

Esempio:

class A: 
    def foo(self): 
     self.bar() 

    def bar(self): 
     print "from A" 

class B(A): 
    def foo(self): 
     self.bar() 

    def bar(self): 
     print "from B" 

Questo significa che un oggetto della classe A obj = A() possa in qualche modo finire per la stampa "di B" ? Sto leggendo questo correttamente? Mi scuso se questo non ha senso. Sono un po 'confuso su come Python gestisce l'ereditarietà e l'override. Grazie!

risposta

6

No. La superclasse non è in grado di sapere nulla della sottoclasse. Significa che se si istanzia la sottoclasse B e si eredita un metodo foo() e si esegue l'override di un metodo bar(), quindi quando si chiama foo(), si chiamerà la definizione bar() in B, non la definizione bar() in A. Questo non è quello lo scrittore della superclasse intendeva - si aspettava che la sua chiamata a bar() andasse alla sua stessa definizione.

0

No, qualsiasi oggetto che è un A richiamerà A.bar e stampa "from A"

Quale metodo override viene chiamato dipende da ciò che l'oggetto è , non ciò che altre classi possono essere derivate da sua classe. Pensa alla classe come a un cookie cutter e all'oggetto come cookie.

+0

Per espandere, la parola d'ordine è perlomeno dovrebbe chiamare un metodo di una classe derivata. 'obj = B()' _would_ print "da B". –

0

Non esattamente:

class A: 
    def foo(self): 
     self.bar() 

    def foo2(self): 
     self.bar2() 

    def bar(self): 
     print "Bar A" 

    def bar2(self): 
     print "Bar2 A" 

class B(A): 
    def bar(self): 
     print "Bar B" 

objA = A() 
objA.foo() 
objA.foo2() 

objB = B() 
objB.foo() 
objB.foo2() 

uscita:

Bar A 
Bar2 A 
Bar B 
Bar2 A 
1

No, significa che se hai seguente oggetto:

class B(A): 
    def bar(self): 
     print "from B" 

e si fa

obj = B() 
obj.foo() 
.210

allora questo stampa from B come foo(), che è definito nella classe di base , chiede bar(), anch'esso definito nella classe base, ma override nella classe derivata.

Almeno questo è come l'ho letto.

1
a = A() 
a.foo() 
b = B() 
b.foo() 
a.bar = b.bar 
a.foo() 

uscita:

from A 
from B 
from B 
0

La mia risposta non necessariamente in contraddizione con quelli pubblicati già, ma tuttavia esse indicano un modo per ottenere la classe di base per la stampa "di B" chiamando la classe di base metodo dalla classe ereditata. La classe base chiama ancora il metodo di classe ereditato mentre sta lavorando dal sé ereditato. Forse questo è il tipo di situazione a cui si riferisce il paragrafo?

class A: 
    def foo(self): 
     self.bar() 

    def bar(self): 
     print("from A") 

class B(A): 
    def foo(self): 
     super().foo() 

    def bar(self): 
     print("from B") 


A().foo() #prints "from A" 
B().foo() #prints "from B" but indirectly through the base class 
0
class A: 
    def f(self): 
     print 'a.f' 
     self.g() 

    def g(self): 
     print 'a.g' 

class B(A): 
    def g(self): 
     print 'b.g' 

b = B() 
b.f() 

# a.f 
# b.g 
Problemi correlati