-- 1. 상속
-------------------------------------------
>>> class Person() :
	def __init__(self, name, age, gender) :
		self.name = name;
		self.age = age;
		self.gender = gender;
		print("Person Init => %s, %d, %s" % (name, age, gender));
	def call(self) :
		print("Person Call");
	def aboutMe(self) :
		print("Person About => %s, %d, %s" % (self.name, self.age, self.gender));
	def __del__(self) :
		print("Person del!");

		
>>> class Employee(Person) :
	def __init__(self, name, age, gender, salary, hirdate) :
		self.salary = salary;
		self.hirdate = hirdate;
		
		Person.__init__(self, name, age, gender);
		print("Employee init => %d, %s" % (salary, hirdate));
	def doWork(self) :
		print("Employee Do Work");
	def aboutMe(self) :
		Person.aboutMe(self);
		print("Employee About => %d, %s" % (self.salary, self.hirdate));
	def __del__(self) :
		Person.__del__(self);
		print("Employee del");

>>> employee = Employee("홍길동", 32, "남", 1200, "18631203");
Person Init => 홍길동, 32, 남
Employee init => 1200, 18631203

>>> employee.call();
Person Call

>>> employee.aboutMe();
Person About => 홍길동, 32, 남
Employee About => 1200, 18631203

>>> employee.doWork();
Employee Do Work

>>> del employee;
Person del!
Employee del


-- 2. 다중 상속
-------------------------------------------
>>> class A() :
	def __init__(self) :
		print("A Init");

>>> class B(A) :
	def __init__(self) :
		A.__init__(self);
		print("B Init");
		
>>> class C(A) :
	def __init__(self) :
		A.__init__(self);
		print("C Init");
		
>>> class D(B, C) :
	def __init__(self) :
		B.__init__(self);
		C.__init__(self);
		print("D Init");
		
>>> d = D();
A Init
B Init
A Init
C Init
D Init


-- 3. 다중 상속 (super를 이용한 부모객체 중복 초기화 방지)
-------------------------------------------
----------------------------------
class A() :
    def __init__(self) :
        print("A init");

        
class B(A) :
    def __init__(self) :
        super().__init__();
        print("B init");

        
class C(A) :
    def __init__(self) :
        super().__init__();
        print("C init");

        
class D(B, C) :
    def __init__(self) :
        super().__init__();
        print("D init");

d = D();
A init
C init
B init
D init


----------------------------------
class A() :
    def __init__(self) :
        print("A init");

        
class B(A) :
    def __init__(self) :
        super().__init__();
        print("B init");

        
class C(A) :
    def __init__(self) :
        super().__init__();
        print("C init");

        
class D(C, B) :
    def __init__(self) :
        super().__init__();
        print("D init");

d = D();
A init
B init
C init
D init



----------------------------------
class A() :
    def __init__(self) :
        print("A init");

class B(A) :
    def __init__(self) :
        print("B init");
        super().__init__();

class C(A) :
    def __init__(self) :
        print("C init");
        super().__init__();

class D(B, C) :
    def __init__(self) :
        print("D init");
        super().__init__();

d = D();
D init
B init
C init
A init


-- 또다른 예시 (ParentB 상위, ParentA 하위로 계승된다. 오른쪽에서 왼쪽순이다.)
----------------------------------
class GrandParent :
    def __init__(self):
        super(GrandParent, self).__init__()
        print("GrandParent")
        
class ParentA(GrandParent) :
    def __init__(self):
        super(ParentA, self).__init__()
        print("Parent A")
        
class ParentB(GrandParent) :
    def __init__(self):
        super(ParentB, self).__init__()
        print("Parent B")        
        
class Child(ParentA, ParentB):
    def __init__(self):
        super(Child, self).__init__()
        print("Child")        


child = Child()
GrandParent
Parent B
Parent A
Child  


-- 메소드 해석순서조회
----------------------------------
Child.__mro__




-- 상위객체 호출방법
----------------------------------
>>> class Animal():
	name = "Animal"
	def roar(self, arg):
		name = arg
		print(self.name, name, "roar")


>>> a = Animal()
>>> a.roar("hahaha")
Animal hahaha roar


>>> class Dog(Animal):
	def speak(self):
		super(Dog, self).roar("Super : speak!")             # super(type, object).roar(.....)
		super().roar("Super : speak")
		Animal.roar(self, "Object : speak")
		self.roar("Self : speak")
		print(self.name)

		
>>> d = Dog()
>>> d.roar("Dog")
Animal Dog roar
>>> d.speak()
Animal Super : speak! roar
Animal Super : speak roar
Animal Object : speak roar
Animal Self : speak roar
Animal