小小糖 发表于 2018-4-23 13:44:53

Python3 学习笔记 -- 继承

先上一个比较简单的单继承语法。在python3中,基类的构造函数不会被自动调用,需要手动调用,同样的
方法也是这样,需要手动调用。可以使用类名称+init方法,也可以使用super语法进行调用。在下面这个例子
中,子类继承了基类的方法和字段。字段会在基类中初始化。



class BaseClass:   
    def __init__(self):
      self.name = 'BaseClass'
      print('BaseCalss: Constructor called')
    def getname(self):
      print('BaseCalss: self name equals ' + self.name)

class DerivedClass(BaseClass):
    def __init__(self):
      super().__init__()
      print('DerivedClass: Constructor called')

if __name__ == '__main__':
    class1 = BaseClass()
    class1.getname()
   
    class2 = DerivedClass()
    class2.getname()
运行结果:

BaseCalss: Constructor called
BaseCalss: self name equals BaseClass
BaseCalss: Constructor called
DerivedClass: Constructor called
BaseCalss: self name equals BaseClass


子类也可以overwrite父类的方法,那么父类的方法就不会被调用,除非手动调用:

class BaseClass:   
    def __init__(self):
      self.name = 'BaseClass'
      print('BaseCalss: Constructor called')
    def getname(self):
      print('BaseCalss: self name equals ' + self.name)

class DerivedClass(BaseClass):
    def __init__(self):
      super().__init__()
      print('DerivedClass: Constructor called')
    def getname(self):
      print('self.name init value is ' + self.name)
      self.name = 'DerivedClass'
      print('DerivedClass: self name equals ' + self.name)

if __name__ == '__main__':
    class1 = BaseClass()
    class1.getname()
   
    class2 = DerivedClass()
    class2.getname()


运行结果:

BaseCalss: Constructor called
BaseCalss: self name equals BaseClass
BaseCalss: Constructor called
DerivedClass: Constructor called
self.name init value is BaseClass
DerivedClass: self name equals DerivedClass



python不仅仅支持单继承,还支持多继承,字段和方法都可以被继承。在多继承super()只能代表继承的第
一个父类,所以您在子类的构造函数中,不能单独使用super().__init__(), 那只是表示调用其中一个基类的
构造函数。所以用super就不是那么好用了。还是要用会原来的类名+init方法来调用。

class BaseClass1:
    def __init__(self):
      self.name1 = 'BaseClass1_Name1'
      self.name = 'BaseClass1_Name'
      print('BaseCalss1: Constructor called')
    def getname1(self):
      print('BaseCalss1: self name1 equals ' + self.name1)
    def getname(self):
      print('BaseCalss1: getname called, name equal ' + self.name)

class BaseClass2:
    def __init__(self):
      self.name2 = 'BaseClass2_Name2'
      self.name = 'BaseClass2_Name'
      print('BaseClass2: Constructor called')
    def getname2(self):
      print('BaseClass2: self name2 equals ' + self.name2)
    def getname(self):
      print('BaseCalss2: getname called, name equal ' + self.name)

class DerivedClass2(BaseClass1, BaseClass2):
    def __init__(self):
      BaseClass1.__init__(self)
      BaseClass2.__init__(self)
      print('DerivedClass: Constructor called')
      
if __name__ == '__main__':
    class1 = BaseClass1()
    class1.getname1()
   
    class2 = BaseClass2()
    class2.getname2()
   
    class3 = DerivedClass2()
    class3.getname1()
    class3.getname2()
    class3.getname()
运行结果:

BaseCalss1: Constructor called
BaseCalss1: self name1 equals BaseClass1_Name1
BaseClass2: Constructor called
BaseClass2: self name2 equals BaseClass2_Name2
BaseCalss1: Constructor called
BaseClass2: Constructor called
DerivedClass: Constructor called
BaseCalss1: self name1 equals BaseClass1_Name1
BaseClass2: self name2 equals BaseClass2_Name2
BaseCalss1: getname called, name equal BaseClass2_Name



我们可以看到,当两个基类有方法重名的时候,python3会按照您继承类的从左到右的顺序查找您调用的方
法DerivedClass2(BaseClass1, BaseClass2)。在这个例子中,是先找BaseClass1,然后再找BaseClass2。

如果您的代码需要多层继承的话,可以参开多重继承的 Diamond Problem 问题。

class A1:
    def foo1(self):
      print("Call A1's foo1")
class A2:
    def foo1(self):
      print("Call A2's foo1")
    def foo2(self):
      print("Call A2's foo2")

class B1(A1,A2):
    pass
class B2(A1,A2):
    def foo2(self):
      print("Call B2's foo2")
      
class C(B1,B2):
    pass

if __name__ == '__main__':
   
    class1 = C()
    class1.foo1()
    class1.foo2()


运行结果:

Call A1's foo1
Call B2's foo2

所以对于python3 的多层继承来说,因为都是新式类,总是从左到右,广度优先的方式进行。

梦想家 发表于 2018-5-9 10:00:52

:victory:
页: [1]
查看完整版本: Python3 学习笔记 -- 继承