从基类调用派生类中重写的方法

8
我正在阅读有关的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()能够以某种方式打印出"from B"?我是否正确理解了这一点?如果我说得不清楚,我很抱歉。我有些困惑Python如何处理继承和覆盖。谢谢!
7个回答

8
不行。超类不可能知道子类的任何信息。这意味着,如果你初始化了子类B,并且它继承了一个方法foo()并且覆盖了一个方法bar(),那么当你调用foo()时,它会调用B中定义的bar()而不是A中定义的bar()。这不是超类编写者的本意-他期望自己调用bar()时会回到他自己的定义中。

如何防止这种情况发生? - ramazan polat

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

输出:

from A
from B
from B

2

我的回答并不一定与已发布的回答相矛盾,但它确实展示了一种通过从继承类中调用基类方法来使基类打印“from B”的方法。基类仍然调用继承类方法,因为它是从继承self中工作的。也许这就是该段落所指的情况?

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
不,这意味着如果您有以下对象:
class B(A):
    def bar(self):
        print "from B"

而且你也这样做

obj = B()
obj.foo()

那么这将打印from B作为foo(),它在基类中定义,调用bar(),它也在基类中定义,但在派生类中被覆盖

至少这是我读到的。


1
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

不完全是这样:

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

不,任何一个是 A 的对象都会调用 A.bar 并打印 "from A"

调用哪个被覆盖的方法取决于对象的本身,而不是其他类可能从它的类派生出来。把类想象成一个饼干模具,把对象想象成饼干。


扩展时,关键词是“可能”调用派生类的方法。obj = B()将打印“来自B”。 - Marc Bollinger

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接