Я читал документы 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 обрабатывает наследование и переопределение. Благодарность!
7 ответов
Нет. Суперкласс не может ничего знать о подклассе. Это означает, что если вы создаете экземпляр подкласса B, и он наследует метод foo()
и переопределяет метод bar()
, то при вызове foo()
это вызовет {{X3} } определение в B, а не bar()
определение в A. Это не то, что намеревался автор суперкласса - он ожидал, что его вызов bar()
пойдет к его собственному определению.
Нет, это означает, что вы, если у вас есть следующий объект:
class B(A):
def bar(self):
print "from B"
И вы делаете
obj = B()
obj.foo()
Тогда это напечатает from B
как foo()
, который определен в базовом классе , вызывает bar()
, который также определен в базовом классе, но переопределено в производном классе .
По крайней мере, так я это прочитал.
Нет, любой объект, который является A
, вызовет A.bar
и напечатает "from A
"
Какой переопределенный метод вызывается, зависит от того, что является объектом , а не от того, какие другие классы могут быть получены из его класса. Думайте о классе как обрезателе печенья, а об объекте - как об печенье.
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
a = A()
a.foo()
b = B()
b.foo()
a.bar = b.bar
a.foo()
Выход:
from A
from B
from B
Мой ответ не обязательно противоречит уже опубликованным, но он показывает способ заставить базовый класс печатать «из 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
Не совсем:
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
Похожие вопросы
Новые вопросы
python
Python - это многопарадигмальный, динамически типизированный, многоцелевой язык программирования. Он разработан для быстрого изучения, понимания и использования, а также для обеспечения чистого и единообразного синтаксиса. Обратите внимание, что Python 2 официально не поддерживается с 01.01.2020. Тем не менее, для вопросов о Python, связанных с версией, добавьте тег [python-2.7] или [python-3.x]. При использовании варианта Python (например, Jython, PyPy) или библиотеки (например, Pandas и NumPy) включите его в теги.