Python面向对象--继承

2017-11-13  本文已影响0人  Bling_ll

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(廖雪峰)

上一篇 下一篇

猜你喜欢

热点阅读