Я читал документы 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() может каким-то образом печатать «из B»? Я правильно это читаю? Я прошу прощения, если это не имеет смысла. Я немного озадачен тем, как python обрабатывает наследование и переопределение. Благодарность!

8
Rex Hunt 19 Июн 2010 в 03:43

7 ответов

Лучший ответ

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

8
ire_and_curses 18 Июн 2010 в 23:48

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

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

И вы делаете

obj = B()
obj.foo()

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

По крайней мере, так я это прочитал.

1
Felix Kling 18 Июн 2010 в 23:51

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

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

0
Tony the Pony 18 Июн 2010 в 23:46
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
BioGeek 12 Апр 2013 в 13:09
a = A()
a.foo()
b = B()
b.foo()
a.bar = b.bar
a.foo()

Выход:

from A
from B
from B
2
animuson 4 Дек 2011 в 05:40

Мой ответ не обязательно противоречит уже опубликованным, но он показывает способ заставить базовый класс печатать «из 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
1
KobeJohn 12 Май 2011 в 02:29

Не совсем:

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
Aren 18 Июн 2010 в 23:49