Note: Please use code tags when you post code, so that the forum can display your code properly.
One way to find out what exactly the flow of a program like this is, is by running it in a debugger. Start the program in the debugger and step through it line by line to see where it goes and what happens to variables.
This program works like this:
1. First, an Extension object is created. Part of the process of initializing the new Extension object is initializing the Base part of the object. That's what happens first. Initially, the member variable i in class Base is initialized with a default value of 0. Then the Base constructor is run, which calls add(1). Note that since we're creating an Extension object, the add() method in class Extension is called (not the add method in class Base!), which sets i to 0 + 1 * 2 = 2.
2. Now the Extension part of the object is initialized. The Extension constructor calls add(2). The add() method in class Extension is called again, so after this, i is set to 2 + 2 * 2 = 6.
3. Then, in method bogo(), add(8) is called on the object. Since b refers to an Extension object and because of polymorphism, add() in class Extension is called (even though b is a Base). So after that call, i is set to 6 + 8 * 2 = 22.
4. print() in class Base is called and the value 22 is printed.