简体   繁体   中英

Calling Overriden Methods in Derived Class from Base Class

I was reading the Python docs about classes and came across this paragraph which I'm not sure about:

Derived classes may override methods of their base classes. Because methods have no special privileges when calling other methods of the same object, a method of a base class that calls another method defined in the same base class may end up calling a method of a derived class that overrides it. (For C++ programmers: all methods in Python are effectively virtual.)

Example:

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"

Does this mean that an object of class A obj = A() can somehow end up printing "from B"? Am I reading this correctly? I apologize if this doesn't make sense. I'm a bit confused as to how python handles Inheritance and overriding. Thanks!

No. There's no way the superclass can know anything about the subclass. What it means is if you instantiate the subclass B, and it inherits a method foo() , and overrides a method bar() , then when you call foo() , that will call the bar() definition in B, not the bar() definition in A. This is not what the superclass writer intended - he expected his call to bar() to go to his own definition.

No, it means that you if you have following object:

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

and you do

obj = B()
obj.foo()

then this will print from B as foo() , which is defined in the base class , calls bar() , which is also defined in the base class, but overridden in the derived class .

At least this is how I read it.

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

output:

from A
from B
from B

My answer doesn't necessarily contradict the ones posted already, but it does show a way to get the base class to print "from B" by calling the base class method from the inherited class. The base class still calls the inherited class method as it is working from the inherited self. Perhaps this is the type of situation the paragraph is referring to?

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

No, any object that is an A will invoke A.bar and print " from A "

Which overridden method is called depends on what the object is , not what other classes may be derived from its class. Think of the class as a cookie cutter, and the object as the cookie.

Not exactly:

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

Output:

Bar A
Bar2 A
Bar B
Bar2 A

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM