美文网首页
Python面向对象--继承

Python面向对象--继承

作者: Bling_ll | 来源:发表于2017-11-13 00:09 被阅读0次

    1、单继承(代码的重用)

    语法:class DerivedClassName(BaseClassName),其中DerivedClassName是派生类,BaseClassName是基类、父类或超类。

    何时使用继承:当你需要定义几个类,而类与类之间有一些公共的属性和方法,这时就可以把相同的属性和方法作为基类的成员,而特殊的方法及属性则在本类中定义,这样只需要继承基类这个动作,就可以访问到基类的属性和方法了,它提高了代码的可扩展性。

    例子1:若子类中定义了与父类同名的方法或属性,则会自动覆盖父类对应的方法或属性。

    class Parent:
        def hello(self):
            print('正在调用父类的方法')
    class Child(Parent):#继承Parent类
        def hello(self): #重写hello方法
            print('正在调用子类的方法')
        def study(self): #可以对子类增加一些方法
            print('学习中')
    >>>p=Parent()
    >>> p.hello()
    正在调用父类的方法
    >>> c=Child()
    >>> c.hello()
    正在调用子类的方法
    

    例子2:当子类与父类中都有__init__方法时,即子类重写了父类的构造方法,此时若不显式调用父类的构造函数,父类的构造函数就不会被执行,导致子类实例访问父类初始化方法中初始的变量就会出现问题。

       class Person:
           def __init__(self):
               self.name ="王小明"
           def func1(self):
               print("function1 is print name:%s"%self.name)
       class Boy(Person):
           def __init__(self):
               self.gender ="male"
           def func2(self):
               print("function2 is print gender:%s"%self.gender)
    
       >>>b=Boy()
       >>>b.gender
       'male'
       >>>b.func2()
       function2 is print gender:male
       >>>b.func1() #会报错
       Traceback (most recent call last):
         File "<pyshell#70>", line 1, in <module>
           b.func1()
         File "<pyshell#50>", line 5, in func1
           print("function1 is print name:%s"%self.name)
       AttributeError: 'Boy' object has no attribute 'name'
     #错误原因:在子类中,构造函数被重写,但新的构造方法没有任何关于初始化父类的name属性的代码!
    

    为了达到预期的效果,子类的构造方法必须调用其父类的构造方法来进行基本的初始化,有两种解决方法:
    方法一:调用未绑定的父类方法

     #修改代码
     class Boy(Person):
         def __init__(self):
            #这一行解决问题,直接使用父类名称调用其构造函数
             Person.__init__(self)
             self.gender ="male"
         def func2(self):
             print("function2 is print gender:%s"%self.gender)
             
     >>> b=Boy()
     >>> b.func1()
     function1 is print name:王小明
     >>> b.func2()
     function2 is print gender:male
     '''
     在调用一个实例的方法时,该方法的self参数会被自动绑定到实例上(称为绑定方法)。但如果直接调用类方法(比如A.__init),那么就没有实例会被绑定。这样就可以自由的提供需要的self参数,这种方法称为未绑定unbound方法。(什么是实例对象、类对象,在后面有讲述)
     '''
    

    方法二:使用super函数

    ```python
    #修改代码
    class Boy(Person):
        def __init__(self):
            #这一行解决问题
            super().__init__()
            self.gender ="male"
        def func2(self):
            print("function2 is print gender:%s"%self.gender)
    
    >>> b=Boy()
    >>> b.func1()
    function1 is print name:王小明
    '''
    super函数会返回一个super对象,这个对象负责进行方法解析,解析过程其会自动查找所有的父类以及父类的父类(即无需给定任何基类的名字),注:self参数已在super()自动传入,在__init__()中将隐式传递,不需要写出(也不能写)。
    '''
    

    方法一更直观,方法二可以一次初始化所有超类!
    super函数比在超类中直接调用未绑定方法更直观,但是其最大的优点是如果子类继承了多个父类,它只需要使用一次super函数就可以。然而如果没有这个需求,直接使用A.init(self)更直观一些。

    super解决钻石继承问题:https://www.tuicool.com/articles/eEzmmay

    2、多重继承(一个子类就可以同时获得多个父类的所有功能)

    语法:class DerivedClassName(Base1,Base2,Base2)

     class Base1:
         def func1(self):
             print('我是func1')
     class Base2:
         def func2(self):
             print('我是func2')
     class Base3(Base1,Base2):
         pass
     >>>c=Base3()
     >>>c.func1()
     我是func1
     >>>c.func2()
     我是func2
    

    Mixin机制:https://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/0013868200511568dd94e77b21d4b8597ede8bf65c36bcd000(廖雪峰)

    相关文章

      网友评论

          本文标题:Python面向对象--继承

          本文链接:https://www.haomeiwen.com/subject/eyqamxtx.html