1. 单继承
类实例化时,会创建一个self对象(本质是一个空字典)代表的就是该类实例化的对象,然后会自动调用__init__()初始化方法,如果该类没有,就去执行父类的初始化方法,但是注意这里的self代表的就是实例化的类生成的对象!!然后执行初始化方法,可以进行赋值,就是给self对象添加属性以及对应的属性值,可以拿着self对象操作对象属性,或者调用方法~
class Animal(): # 定义类 def __init__(self): # 初始化方法 print("执行Animal的__init__()方法") self.func() # 类内调用类中的其他方法,这里的self就是实例化的对象 def eat(self): # 定义方法 print("%s 正在吃。。。"%self.name) def drink(self): print('%s 正在喝。。。'%self.name) def func(self): print("Animal的func") class Dog(Animal): # 定义类,从Animal类继承,没有的话继承,有的话覆盖?? def bite(self): print("%s 会咬人"%self.name) def func(self): # Dog()类重新定义了func()方法 print("小狗的func函数") lunck=Dog() # 对Dog()类进行实例化为一个对象,这时候就会创建一个self对象(本质是一个空字典)然后执行__init__()初始化方法,但是Dog()类中并没有,所以去执行父类Animal中的__init__()方法 # 但是要注意self,是实例化的对象,在这里self它是由Dog类实例化的,代表的是Lucky 所以self.func()应该是Dog.func(lucky)《==》lunck.func()
运行结果:
执行过程:
也就是说子类继承父类,当子类去调用一个方法时,如果子类中有该方法,就直接用自己的,子类中没有才去调父类的方法;
2.派生-----派生属性
子类继承父类,子类中有的属性,但是父类中没有这个属性,则该属性就叫派生属性;
class Animal(): def __init__(self,name,hp,attr): self.name=name self.hp=hp self.attr=attr def eat(self): print("%s 正在吃。。。"%self.name) def drink(self): print("%s正在喝..."%self.name) class Dog(Animal): def __init__(self,name,hp,attr,kind): Animal.__init__(self,name,hp,attr) # 这是父类中有的属性,由于字类也有__init__()方法所以在又想使用父类的相关属性的话,只能这样调用:父类名.__init__(self,父类中的属性) # 这里的self参数一定要传的,这里self表示对象,是指子类实例化的对象Dog(),而且这个self是在Dog()类实例化之后立马创建的一个对象(空字典)发生在调用__init__()方法之前!!
# 因为父类在实例化一个对象时 直接Animal() 这样实例化就创建了自己的self self.kind=kind # 父类Animal中没有的属性kind 字类Dog()中有该属性,该属性就叫派生属性 lucky=Dog('lucky',100,3,'哈士奇') print(lucky.name)
3. 派生---派生方法
子类中有的方法父类中没有,该方法就叫派生方法;
class Animal(): def __init__(self,name,hp,aggr): self.name=name self.hp=hp self.aggr=aggr def eat(self): print("%s 正在吃...."%self.name) def drink(self): print("%s正在喝..."%self.name) class Dog(Animal): def __init__(self,name,hp,aggr,kind): Animal.__init__(self,name,hp,aggr) # 从父类继承相关属性,是因为子类也有一个__init__()方法,当Dog()实例化时首先创建一个self对象,然后调用__init__()方法,自己有们就调用自己的,所以不去调用父类的__init__()方法了 # 但是又想使用父类的那些属性,就要使用父类.__init__(self,父类中有的属性)调用,这里的self一定要写, #并且self指的是子类在进行实例化时创建的对象,是在调用初始化方法之前,一旦进行类实例化,就立马产生一个self对象,然后才开始调用__init__方法 self.kind=kind # 派生属性 def bite(self): # 派生方法,父类中没有该方法,但是子类中有的方法 print("%s会咬"%self.name) lucky=Dog('lucky',100,2,'哈士奇') print(lucky.name) # name是父类的属性,子类没有的,想使用可以继承 print(lucky.kind) # kind是子类特有 父类没有的属性,又叫派生属性 lucky.eat() # 父类中有,子类中没有,子类可以调用 lucky.bite() # 派生方法,父类没有该方法,子类含有
运行结果:
父类中有一个方法,子类中也有该方法,当子类调用该方法时,由于子类中有所以会调用子类中的方法,但是如果还想使用父类的那个方法,也就是想在父类方法的基础上进行扩展功能:
class Animal(): def __init__(self,name,hp,aggr): self.name=name self.hp=hp self.aggr=aggr def eat(self): print("%s 正在吃...."%self.name) def drink(self): print("%s正在喝..."%self.name) class Dog(Animal): def __init__(self,name,hp,aggr,kind): Animal.__init__(self,name,hp,aggr) # 从父类继承相关属性,是因为子类也有一个__init__()方法,当Dog()实例化时首先创建一个self对象,然后调用__init__()方法,自己有们就调用自己的,所以不去调用父类的__init__()方法了 # 但是又想使用父类的那些属性,就要使用父类.__init__(self,父类中有的属性)调用,这里的self一定要写, # 并且self指的是子类在进行实例化时创建的对象,是在调用初始化方法之前,一旦进行类实例化,就立马产生一个self对象,然后才开始调用__init__方法 self.kind=kind # 派生属性 def eat(self): # 子类中有该方法,父类中也有该方法,子类调用该方法,肯定是执行子类的这个eat()方法, Animal.eat(self) # 但是如果还想执行父类的方法,也就是扩展父类的eat方法,就需要使用父类.eat(self,父类方法的其他参数) print('吃完之后%s长胖了(这是执行子类的eat()方法,在父类eat方法的基础上进行扩充的~)'%self.name) def bite(self): # 派生方法,父类中没有该方法,但是子类中有的方法 print("%s会咬"%self.name) lucky=Dog('lucky',100,2,'哈士奇') print(lucky.name) # name是父类的属性,子类没有的,想使用可以继承 print(lucky.kind) # kind是子类特有 父类没有的属性,又叫派生属性 lucky.bite() # 派生方法,父类没有该方法,子类含有 lucky.eat() # 父类中有,子类中也有,子类调用子类中的方法,又想执行父类中相应的方法,也就是对父类相应方法做了一下扩展
运行结果:
总结:
1. 子类对象调用子类中有的名字(包括属性和方法)一定要用子类的,子类中没有的才去调用父类的;
2. 当子类没有__init__()初始化方法时,实例化子类得到对象,首先创建一个self对象,然后采取执行初始化__init__()方法,子类中没有,就去调用父类的__init__()初始化方法;
但是如果子类也有初始化__init__()方法,但是里面的属性需要继承父类的某些属性,就可以在子类__init__()初始化方法中使用父类名.__init__(self,父类初始化的其他参数),这里面的参数self对象一定要写,表示子类实例化的对象,接下来可以使用子类自己的派生属性;
3. 当子类实例化的对象去调用子类中没有的方法时,就去父类中找,找到就调用父类的该方法;
4. 当子类实例化的对象去调用子类中有但是父类中也有的方法时,那肯定是调用自己类中定义的方法,而不是去调用父类的相应重名方法。但是如果子类调用一个自己类中有的方法,但是想继续使用父类的相应方法,其实就是想在父类相应方法的基础上扩展功能,,增加上自己类独有的特性,就可以在子类的该重名方法中加上父类名.父类方法(self,父类该方法的别的参数),就可以在子类调用该方法时 ,调用自己类中的方法同时调用父类相应方法~