zoukankan      html  css  js  c++  java
  • 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 的多层继承来说,因为都是新式类,总是从左到右,广度优先的方式进行。

    本例子代码可以从这里下载。

  • 相关阅读:
    简单字符串处理应避免使用正则表达式
    提高正则表达式的可读性
    用零宽度断言匹配字符串中的特定位置
    避免不必要的回溯
    预编译正则表达式
    用Text::CSV_XS模块处理csv文件
    Ack 类似grep一样的查找
    Apache压力测试
    仅编译正则表达式一次
    排序上下箭头的是实现
  • 原文地址:https://www.cnblogs.com/haoxinyue/p/python3_Inheritance.html
Copyright © 2011-2022 走看看