一. 单继承
定义一个动物类Animal为基类,它基本两个实例属性name和age、一个方法call
定义一个Cat 猫类继承于Animal,猫类比动物类多一个sex属性
实例猫类对象,调用父类的属性和方法
# 解题的思路
'''类(类名,属性,方法)
几个类:动物类、猫类
类之间的关系:猫类继承动物类
类名:Animal
属性:1-类属性 2-实例属性
姓名-name
年龄-age
功能:
叫-call()
类名:Cat
属性:
姓名-name
年龄-age
性别-sex
class Animal():
name = '动物'
__age = 1
def call(self):
print('动物都会叫')
def __info(self):
print('动物的信息')
class Cat(Animal):
sex = '公'
# 继承后,子类的实例对象可以访问父类公有的属性和方法
c1 = Cat()
c1.name = '猫咪'
print(c1.name) #动物
c1.call()
print(c1.__age) #AttributeError: 'Cat' object has no attribute '__age'
总结:子类可以直接使用父类的公有属性和方法,但是对于父类私有的属性则不可以调用
二. 构造方法的继承
情况一:父类有构造方法,子类没有时,在实例化子类对象时会自动调用父类的构造方法,
即子类自动继承父类的构造方法
情况二:当子类的构造方法实现与父类构造方法部分一直,但是子类有添加的部分属性,
则可以在子类的构造方法中先继承父类的构造方法,再扩写构造方法。即构造方法的扩写。
子类继承父类构造方法的语法:
super(子类名,self).__init__(参数1,参数2,....)
父类名.__init__(self,参数1,参数2,...)
情况三:当子类不需要使用父类的构造方法时,可以在子类中重新写一个构造方法,
那么在实例化子类对象时,只会调用本子类的构造方法,而不会调用父类的构造方法。即构造方法的重写。
案例2:
定义一个动物类Animal为基类,它有两个实例属性name和age、一个方法call
定义一个Cat 猫类继承于Animal,猫类比动物类多一个sex属性
实例猫类对象,调用父类的属性和方法
类(类名,属性,方法)
几个类:动物类、猫类
类之间的关系:猫类继承动物类
类名:Animal
属性:1-类属性 2-实例属性
姓名-name
年龄-age
功能:
叫-call()
类名:Cat
属性:
姓名-name
年龄-age
性别-sex
# class Animal():
# def __init__(self,name,age):
# self.name = name
# self.__age = age
#
# def call(self):
# print('动物都会叫')
#
# def __info(self):
# print('动物的信息')
#
# class Cat(Animal):
# sex = '公' #类属性方式
#
#
# # 情况一:自动继承父类的构造方法
# # 当子类没有构造方法,但是继承的父类有构造方法的时候,此子类会自动继承父类的构造方法
# # 因此在实例化对象的时候,必须对父类的构造方法中自定义的参数传值
#
# c1 = Cat('猫咪',2) # 什么时候要传参?只有在构造方法中有自定义的参数的时候,才需要传参
# # 调用本类的属性
# print(c1.sex)
# print(Cat.sex)
# # 调用父类的属性和方法
# print(c1.name)
# c1.call()
# 情况二:子类的扩写父类的构造方法
子类继承父类构造方法的语法:
super(子类名,self).__init__(参数1,参数2,....)
父类名.__init__(self,参数1,参数2,...)
# class Animal():
# def __init__(self,name,age):
# self.name = name
# self.age = age
#
# def call(self):
# print('动物都会叫')
#
# def __info(self):
# print('动物的信息')
# class Cat(Animal):
# def __init__(self,name,age,sex):
# # 继承父类的构造方法
# Animal.__init__(self,name,age) # 推荐
# # super(Cat,self).__init__(name,age)
# # 扩写父类的构造方法
# self.sex = sex
#
# def info(self):
# print('名字:{},年龄:{},性别:{}'.format(self.name,self.age,self.sex))
#
# c1 = Cat('加菲猫',100,'公')
# c1.info()
# 情况三:子类的重写父类的构造方法
class Animal():
def __init__(self,name,age):
self.name = name
self.age = age
def call(self):
print('动物都会叫')
def __info(self):
print('动物的信息')
class Cat(Animal):
def __init__(self,name,age,sex):
self.name = name
self.age = age
self.sex = sex
def info(self):
print('名字:{},年龄:{},性别:{}'.format(self.name,self.age,self.sex))
c1 = Cat('加菲猫',100,'公')
c1.info()
在继承中,总之一句话,自己类中有的东西优先使用,自己没有的东西,程序会从父类中查找,父类有,则调用
父类没有,则报错
三.实例方法的重写与扩写
案例:
定义一个动物类Animal为基类,它有两个实例属性name和age、一个方法call
定义一个Cat 猫类继承于Animal,猫类比动物类多一个sex属性,一个方法call
实例猫类对象,调用父类的属性和方法
# 重写
# class Animal():
# def __init__(self,name,age):
# self.name = name
# self.age = age
#
# def call(self):
# print('动物都会叫')
#
# def info(self):
# print('动物的信息,姓名:{},年龄:{}')
#
# class Cat(Animal):
# def __init__(self,name,age,sex):
# self.name = name
# self.age = age
# self.sex = sex
# # 父类方法的重写
# def call(self):
# print('猫喵喵叫')
#
# def info(self):
# print('名字:{},年龄:{},性别:{}'.format(self.name,self.age,self.sex))
#
# c1 = Cat('加菲猫',100,'公')
# c1.call()
# 扩写
# 调用语法:
# 父类名.实例方法名(self,参数1,参数名2...)
class Animal():
def __init__(self,name,age):
self.name = name
self.age = age
def call(self,name):
print('{}都会叫'.format(name))
def info(self):
print('动物的信息,姓名:{},年龄:{}')
class Cat(Animal):
def __init__(self,name,age,sex):
self.name = name
self.age = age
self.sex = sex
# 父类方法的扩写
def call(self,name):
# 调用父类实例方法
Animal.call(self,name)
# 增加新的功能
print('猫喵喵叫')
def info(self):
print('名字:{},年龄:{},性别:{}'.format(self.name,self.age,self.sex))
c1 = Cat('加菲猫',100,'公')
c1.call('hhh')
四.继承的传递性
子类可以继承父类公有的属性和方法
子类也可以继承父类的父类的公有属性和方法
案例:
定义一个动物类Animal为基类,它有两个实例属性name和age、一个方法call
定义一个Cat 猫类继承于Animal,猫类比动物类多一个sex属性
定义一个HelloKitty类继承于Cat,HelloKitty类比猫类多一个speak方法
实例HelloKitty类对象,调用父类及父类的父类中公有的属性和方法
class Animal():
def __init__(self,name,age):
self.name = name
self.age = age
def call(self,name):
print('{}都会叫'.format(name))
def info(self):
print('动物的信息,姓名:{},年龄:{}')
class Cat(Animal):
def __init__(self,name,age,sex):
self.name = name
self.age = age
self.sex = sex
# 父类方法的扩写
def s(self,name):
# 调用父类实例方法
Animal.call(self,name)
# 增加新的功能
print('猫喵喵叫')
def a(self):
print('名字:{},年龄:{},性别:{}'.format(self.name,self.age,self.sex))
class HelloKitty(Cat):
def __init__(self,name,age,sex):
self.name = name
self.age = age
self.sex = sex
def speak(self):
print('我是{},我会说话'.format(self.name))
hk = HelloKitty('凯蒂',3,'母')
# 调用父类的方法
hk.a()
# 调用父类的父类的方法
hk.call('凯蒂')
总之:继承的传递性就是子类的实例对象会优先在父类中查找,如果父类有,则直接使用,如果父类没有,
则进入父类的父类中查找,如果存在,则调用,不存在,则报错。
五.多继承
多继承可以让子类对象,子类可以同时调用多个父类的公有属性和方法
多继承语法:
class 类名(父类1,父类2):
子类属性
子类特有的方法
案例:
定义一个神仙类和猴子类,再定义一个孙悟空类,孙悟空类分别继承神仙类和猴子类
神仙类有飞的实例方法
猴子类有吃的实例方法
孙悟空类有取经的实例方法
实例孙悟空对象,分别调用父类的属性和方法
解题思路
3个类:神仙类和猴子类、孙悟空类
关系:子类-孙悟空类 父类:神仙类和猴子类
class ShenXian():
def fly(self):
print('神仙都会飞')
def info(self):
print('神仙')
class Monkey():
def eat(self):
print('猴子爱吃桃')
def info(self):
print('猴子')
class SunWuKong(ShenXian,Monkey): #多继承
def study(self):
print('孙悟空和唐僧去西天取经,历经九九八十一难')
swk = SunWuKong()
swk.info() # 按照多继承父类的先后排列顺序来调用
swk.fly()
swk.eat()
swk.study()