一、继承:简化代码避免重复
继承的意思相当于把父类中可以使用的方法写在自己类中一个性质
例1:创建一个人类,分男人类与女人类
属性:姓名、年龄
方法:吃、走 ====》公共特征
男:方法==》上班
女:方法==》洗衣服
class People: # 父类,可以理解为一个较为抽象的类,具体细分由下面的子类完成
# 公共代码放置位置
def __init__(self,name,age):
self.name=name
self.age=age
def run(self):
print('%s走路'%self.name)
def eat(self):
print('吃东西')
# 继承People类:继承的意思相当于把以上可以使用的方法写在自己的类中一个性质
class man(People): # 男人类
def work(self):
print('%s上班'%self.name)
# 继承People类
class woman(People):
# class woman(man):
def watch(self):
print('%s洗衣服'%self.name)
# 实例化
xiaoming=man('小明',20)
xiaoming.run()
xiaoming.work()
#
xiaohua=woman('小花',19)
xiaohua.run()
xiaohua.watch()
# xiaohua.work() # 不能访问小明的方法,子类之间的方法不可以互相访问,除非woman继承man类
# __bases__查看类继承的直接父级(通过类名)
print(woman.__bases__) # (<class '__main__.man'>,) 继承
print(man.__bases__) # (<class '__main__.A'>,) 继承people
print(People.__bases__) # (<class 'object'>,)
# print(xiaohua.__bases__) # 错误写法
运行截图:
例2:多继承:
重写:当子类继承父类之后,如果子类不想使用父类的方法,可以通过重写来覆盖父类的方法
class base:
def __init__(self,name,age):
self.name=name
self.age=age
def run(self):
print('%s走路'%self.name)
def eat(self):
print('吃东西')
class Father(base): # 爸爸类
def work(self):
print('%s上班'%self.name)
def cook(self):
print('%s做饭好难吃'%self.name)
class Mother(base): # 妈妈类
def watch(self):
print('%s洗衣服' % self.name)
def cook(self):
print('%s做饭真好吃'%self.name)
# 如果Father在前面先继承Father类,优先级
class Son(Father,Mother):
# 重写:当子类继承父类之后,如果子类不想使用父类的方法,可以通过重写来覆盖父类的方法
def cook(self):
# pass
print('%s做饭最好吃!!!'%self.name)
xiaoming=Son('小明',20)
#
xiaoming.watch()
xiaoming.work()
xiaoming.run()
xiaoming.eat()
xiaoming.cook() # Father在前面先继承
print(Son.__mro__) # 查询类继承的顺序== 调用方法的时候依次查询 object是所有类的父类
运行截图:
例3:重写父类方法之后,如果又需要使用父类的方法呢?
super().money() # 如果自己的资金不够就把父类的也拿过来
super 函数可以调用父类的方法,在父类中也可以使用super函数
Father.cook(self) # 这样写先继承Father类===》可以理解准确性的继承
class base:
def __init__(self,name,age):
self.name=name
self.age=age
def run(self):
print('%s走路'%self.name)
def eat(self):
print('吃东西')
class Father(base):
def work(self):
print('%s上班'%self.name)
def cook(self):
print('%s做饭好难吃'%self.name)
def money(self):
print('爸爸有10万')
class Mother(base): # 多继承
def watch(self):
print('%s洗衣服' % self.name)
def cook(self):
print('%s做饭真好吃'%self.name)
def money(self):
print('妈妈有5万')
class Son(Mother,Father): # 哪个在前面先继承哪个类
def cook(self): # 重写(新建一个新的类与父类方法名一样的时候),重写就不再使用父类的方法
# pass
super().cook() # 在使用的重写的时候再去拿父级的方法,重写了的话就使用自己的
# super().watch()
Father.cook(self) # 这样写先继承Father类===》可以理解准确性的继承
print('%s做饭最好吃!!!'%self.name)
def money(self):
super().money() # 如果自己的资金不够就把父类的也拿过来
Father.money(self) # 继承爸爸类
print('我有一万!!!')
xiaoming=Son('小明',20)
xiaoming.watch()
xiaoming.work()
xiaoming.run()
xiaoming.eat()
xiaoming.cook() # Mother在前面先继承
xiaoming.money()
print(Son.__mro__) # 查询类继承的顺序== 调用方法的时候依次查询
运行截图:
二、魔术方法
思考:字符串拼接的时候,字符串可以直接相加,那我们自定义的类可以实现吗?
例1:
class Rectangle: # 英 [ˈrektæŋɡl] 长方形、矩形 def __init__(self,length,width): self.length = length self.width = width def __add__(self,other): # __add__两个实例相加的时候触发这个魔术方法 add_length = self.length + other.length add_width = self.width + other.width return add_length,add_width def Area(self): areas = self.length * self.width return areas # 实例a,b a = Rectangle(3,4) b=Rectangle(5,7) print(a+b) print(a.Area())
# 以上非重点内容,以下代码为重点内容
运行截图:
例2:str与repr知识点
1.在交互模式下输出的交互信息与 直接print的信息有些不同, 背后的原理是 ?
交互式模式使用repr方法
2.我们该如何使用这种机制 ?
3.类的实例可以向函数一样被调用吗?
正常情况下,实例是不能像函数一样被调用的,要想实例能够被调用,就需要定义 __call__ 方法
class Rectangle: # 类名后面可以不用括号 # class Rectangle(object):
def __str__(self): # 打印实例名的时候会触发(自己调用)__str__方法
print(123)
return '1232' # 只可以返回字符串,必须要有return
# return 123 # 错误写法
# return [123] # 错误写法
# def __repr__(self): # 在开发时在调试的时候应用,即交互式模式下
#
# return '1236666' # 只可以返回字符串,必须要有return
# # print(123) # 错误写法,必须是字符串
def __call__(self, *args, **kwargs): # 实例名加括号会触发这个方法
print('123111100000000000')
return '1231111'
r = Rectangle() # 创建实例化
print(r) # str方法
print(r.__class__) # 查看类名
r() # call方法
print(r())
# print(123)
运行截图:
例3:常见的魔术方法
class Rectangle:
'''
对于类的注释一般写在这里,比如用户注册
账号:
密码:
'''
name='小明'
def __init__(self,age):
self.age=age
r = Rectangle(19) # 创建实例化
print(r.__dict__) # 查看全部属性,返回属性和属性值键值对形式
print(r.__doc__) # 查看对象文档,即类中(用三个引号引起来的部分)
print(Rectangle.__bases__) # 查看父级
print(Rectangle.__mro__) # 查看多继承的顺序
运行截图:
练习题:
定义正方形类(继承矩形类),实现类的 实例可调用,调用时打印周长;
同时,直接 打印类实例 时能够打印出实例的面积
class Rectangle: # 英 [ˈrektæŋɡl] 长方形、矩形 def __init__(self,length,width): self.length = length self.width = width def Area(self): areas = self.length * self.width # return areas return '该面积为:%s'%areas # 正方形类 class Square(Rectangle): # 因为正方形只需一条边,所以需要重写__init__方法,满足自身需求 def __init__(self,width): self.width=width def __call__(self, *args, **kwargs): print('周长为:%s'%(self.width*4)) def __str__(self): return '面积为:%s'%(self.width*self.width) s=Square(5) s() # 实例调用触发 Call 方法 print(s) # 打印实例 ===》触发str方法
运行截图: