Вызов переопределенных методов в производном классе из базового класса - PullRequest
8 голосов
/ 19 июня 2010

Я читал документы Python о классах и наткнулся на этот абзац, в котором я не уверен:

Производные классы могут переопределять методы своих базовых классов.Поскольку у методов нет специальных привилегий при вызове других методов того же объекта, метод базового класса, который вызывает другой метод, определенный в том же базовом классе, может в конечном итоге вызвать метод производного класса, который переопределяет его.(Для программистов на C ++: все методы в Python являются виртуальными.)

Пример:

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"

Означает ли это, что объект класса A obj = A() может каким-то образом оказаться в конечном итоге?печать "из Б"?Я правильно это читаю?Я прошу прощения, если это не имеет смысла.Я немного озадачен тем, как python обрабатывает наследование и переопределение.Спасибо!

Ответы [ 7 ]

7 голосов
/ 19 июня 2010

Нет.Суперкласс не может ничего знать о подклассе.Это означает, что если вы создаете экземпляр подкласса B, и он наследует метод foo() и переопределяет метод bar(), то при вызове foo() это вызовет определение bar() в B, а не bar() определение в А. Это не то, что намеревался автор суперкласса - он ожидал, что его призыв к bar() пойдет к его собственному определению.

1 голос
/ 15 февраля 2011
a = A()
a.foo()
b = B()
b.foo()
a.bar = b.bar
a.foo()

выход:

from A
from B
from B
1 голос
/ 19 июня 2010

Нет, это означает, что вы, если у вас есть следующий объект:

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

и вы делаете

obj = B()
obj.foo()

тогда будет напечатано from B как foo(), которое определено в базовом классе , вызывает bar(), которое также определено в базовом классе, но переопределено в производный класс .

По крайней мере, так я читаю.

0 голосов
/ 06 марта 2013
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
0 голосов
/ 12 мая 2011

Мой ответ не обязательно противоречит уже опубликованным, но он показывает способ заставить базовый класс печатать «из B», вызывая метод базового класса из унаследованного класса. Базовый класс по-прежнему вызывает метод унаследованного класса, поскольку он работает от унаследованного «я». Возможно, это тот тип ситуации, на который ссылается абзац?

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 голосов
/ 19 июня 2010

Не совсем:

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()

Выход:

Bar A
Bar2 A
Bar B
Bar2 A
0 голосов
/ 19 июня 2010

Нет, любой объект, который является A, вызовет A.bar и напечатает "from A"

Какой переопределенный метод вызывается, зависит от того, чем является объект , а не от того, какие другие классы могут быть получены из его класса. Думайте о классе как обрезателе печенья, а об объекте - как об печенье.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...