-1

I have a question about python inherited class method, in the following code.

class B(object):
    def test(self):
        self.call()
    def call(self):
        print("Call from B")

if __name__ == "__main__":
    b = B()
    b.test()


from b import B

class C(B):
    def call(self):
        print("Call from C")

if __name__ == "__main__":
    c = C()
    c.test()

When I run this code, the result is

Call from C

The parent class method will call children's method. I want to know if it is an expected and stable behaviour? Because I also try the same logic in C++, it will print

Call from B
codeforester
  • 39,467
  • 16
  • 112
  • 140
杨嘉辰
  • 108
  • 1
  • 7
  • Is your question about whether Python has polymorphism? If so [the answer is yes it does](https://stackoverflow.com/questions/3724110/practical-example-of-polymorphism) – Cory Kramer May 31 '18 at 21:37
  • Thank you for the reply. I just wonder why there is a difference between C++ and python. – 杨嘉辰 May 31 '18 at 21:40
  • Works perfectly fine https://repl.it/repls/CoralComplicatedInstructions – imreal May 31 '18 at 21:43
  • "_why there is a difference between C++ and python_" Because they are 2 different languages and don't at all have to function exactly the same. – takendarkk May 31 '18 at 21:44

2 Answers2

3

Yes, this is expected. c is an instance of C, but since C.test is not defined, c.test resolves to B.test. However, the corresponding call to self.call() invokes C.call because the runtime type of self is C, not B, and C.call is defined. Think of all Python methods as being virtual methods.

chepner
  • 497,756
  • 71
  • 530
  • 681
2

As a complement to chepner's answer, this C++ code exhibits the exact same behaviour as you have in Python:

#include <iostream>

class B {
public:
    void test() {
        call();
    }
    virtual void call() {
        std::cout << "Called from B" << std::endl;
    }
};

class C: public B {
public:
    void call() {
        std::cout << "Called from C" << std::endl;
    }
};

int main() {
   C c;
   c.test();        // will print Called from C
   return 0;
}

If you come from C++ think that all members are public, and all methods virtual.

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
  • Thanks; I spent 20 minutes trying to write roughly this same thing ;) (only I used `C *c = new C();` in a mistaken belief that pointers were somehow necessary to invoke virtual method behavior.) – chepner May 31 '18 at 22:01
  • Thanks, I figure out why I didn't get the same result in C++, I forget using keyword virtual. – 杨嘉辰 May 31 '18 at 22:19