[Python][C++] static method and inheritance

[code language=”cpp”]
#include <iostream>

using namespace std;

class Parent {
public:
void foo() {
cout << "foo of parent" << endl;
}
static void static_foo() {
cout << "static_foo of parent" << endl;
}
};

class Child : public Parent {
public:
void foo() {
cout << "foo of child" << endl;
}
static void static_foo() {
cout << "static_foo of child" << endl;
}
};

class DummyChild : public Parent {};

void demo() {
Parent parent;
Child child;
DummyChild dummyChild;

parent.foo(); //foo of parent
Parent::static_foo(); //static_foo of parent

child.foo(); //foo of child
Child::static_foo(); //static_foo of child

dummyChild.foo(); //foo of parent
DummyChild::static_foo(); //static_foo of parent

Parent *parentPtr;
Child *childPtr;

parentPtr = &child;
parentPtr->foo(); //foo of parent
//在一般的情況下 因為cpp是靜態語言 預設只會去找這個pointer class所屬的member function

childPtr = &child;
childPtr->foo(); //foo of child
}
[/code]

[code language=”cpp”]
class VirtualParent {
public:
//member function前面加個virtual就變成virtual function
//後面再加上 = 0;就是pure virtual function
virtual void foo() = 0;
virtual void foo2() {} //實作virtual function不是良好設計 但仍可編譯
};

class NonVirtualChild : public VirtualParent {
public:
//child必須實作pure virtual function
void foo() {
cout << "non virtual child" << endl;
}
//若parental有實作virtual function, child建議要overwrite
//但非強制overwrite
void foo2() {}
};

void demo1() {
//含有pure vitual function的class無法生成instance
//此class又稱abstract class(c++術語)或是interface(抽象講法)
//VirtualParent p;

NonVirtualChild c;
c.foo(); //non virtual child
}

class ConcreteParent {
public:
virtual void foo() {
cout << "concrete parent" << endl;
}
};

class ConcreteChild : public ConcreteParent {
public:
virtual void foo() {
cout << "concrete child" << endl;
}
};

void demo2() {
ConcreteParent* p = new ConcreteChild();
p->foo(); //concreate child;
//若呼叫的是virtual function, pointer會去table找出真正的member function
delete p;
}

int main() {
demo();
demo1();
demo2();
}

[/code]

[code language=”python”]
#Python
class Parent:
variable_foo = "variable_foo" #也是class variable
class_variable_foo = "class_variable_foo"

def __init__(self):
self.variable_foo = "init_foo" #object variable

def foo(self):
print("foo of parent, variable = {}, {}".format(self.variable_foo, self.class_variable_foo))

@staticmethod
def static_foo(*arg):
print("static_foo of parent: arg = {}".format(arg))

@classmethod
def class_foo(cls):
print("class_foo of parent, variable = {}, {}".format(cls.variable_foo, cls.class_variable_foo))

class Child(Parent):
variable_foo = "child_variable_foo" #也是class variable

def __init__(self):
self.variable_foo = "init_child_foo" #object variable

def foo(self):
print("foo of child, variable = {}, {}".format(self.variable_foo, self.class_variable_foo))

@staticmethod
def static_foo(*arg):
print("static_foo of child: arg = {}".format(arg))

@classmethod
def class_foo(cls):
print("class_foo of child, variable = {}, {}".format(cls.variable_foo, cls.class_variable_foo))

class DummyChild(Parent):
pass

parent = Parent()
parent.foo() # foo of parent, variable = init_foo, class_variable_foo
#Python會先去找object的variable 找不到時才會去找class的variable

Parent.class_foo() # class_foo of parent, variable = variable_foo, class_variable_foo
Parent.variable_foo = "changeable"
Parent.class_foo() # class_foo of parent, variable = changeable, class_variable_foo
#在Python裡面 class也是一個object 故在執行期改變class變數是OK的
#在C++ class不是object而是一個namespace 故呼叫class static function要用"::" 而非"."

Parent.static_foo() # static_foo of parent: arg = ()
Parent.static_foo("argument1", "arguments2") # static_foo of parent: arg = (‘argument1’, ‘arguments2’)
#在Python裡面 static method是沒辦法access class的attribute
#故可了解 Python的class method其實比較像C++的class static method

child = Child()
child.foo() # foo of child, variable = init_child_foo, class_variable_foo
child.class_foo() # class_foo of child, variable = child_variable_foo, class_variable_foo
child.static_foo() # static_foo of child: arg = ()

dummy = DummyChild()
dummy.foo() # foo of parent, variable = init_foo, class_variable_foo
DummyChild.class_foo() # class_foo of parent, variable = changeable, class_variable_foo
DummyChild.static_foo() # static_foo of parent: arg = ()
[/code]