面向对象之继承
对象独有的方法
class Person:
h_type = '人类'
def __init__(self, name): # 让对象有用独有的数据每次传入的不一样那么就会产生不一样的数据
self.name = name # 定义在类中的函数我们称之为方法
def eat(self):
print('%s准备干饭'% self.name)
def others(self, a, b):
print('来自others')
"""
真正意义上对象独有的方法我们并不可能实现,我们在全局中定义的对象那么他就不是独有的,然而在类中定义的对象她又是公共的,针对这个问题python添加了一个非常牛的特征,只要是定义在类中的函数默认是将他绑定给对象也就是只要他来了获取走了那么就是单独属于他的对象,几乎不会出现那种绑定对象一致的情况。
"""
p1 = Person('Joseph')
p1.eat() # Joseph准备干饭
p2 = Person('Trump')
p2.eat() # Trump准备干饭
p3 = Person('Alice')
p3.eat() # Alice准备干饭
p1 = Person('zoey')
p1.others(1, 2) # 默认传入自己 来自others
Person.others(p1, 1, 2) # 主动调用自己 来自others
![image](https://img2022.cnblogs.com/blog/2904194/202207/2904194-20220727193254116-113015732.png)
动静态方法
1.什么是方法
其实就是针对在类体代码中编写的函数,每次传入都会导出独属于自己的数据,这种我们称之为方法
2.绑定给对象的方法
直接在类体代码中编写并调用就好了
对象调用的时候会自动将自己本身当作一个对象传入类中的函数体代码,所以就会产生一个独属于自己的数据也就是方法
类体函数有几个形参就需要传给他几个实参
3.静态方法 (其实就是最普通的有参函数)
class Game:
game_name = 'LOL'
# 绑定给对象的方法
def kill_enemy(self): # self来接收对象
print('你可也太强了', self)
@classmethod # 绑定给类的方法
def kill_nash_baron(cls): # 接受对象
print('大哥带带我', cls)
@staticmethod # 静态方法
def get_out(a, b): # 常规函数
print('自己一个人去玩吧,你可也太菜了')
Game1 = Game()
Game.kill_enemy(Game) # 你可也太强了 <class '__main__.Game'>
Game1.kill_enemy() # 你可也太强了 <__main__.Game object at 0x000001D86BB18C70>
Game.kill_nash_baron() # 大哥带带我 <class '__main__.Game'>
Game1.kill_nash_baron() # 大哥带带我 <class '__main__.Game'>
# 调用最普通的有参函数
Game.get_out(1, 2) # 自己一个人去玩吧,你可也太菜了
Game1.get_out(1, 2) # 自己一个人去玩吧,你可也太菜了
![image](https://img2022.cnblogs.com/blog/2904194/202207/2904194-20220727193925945-147721506.png)
三大特征之继承
1.三大特征
1.1 继承
1.2 封装
1.3 多态
2.继承
这里的继承其实和我们现实生活中差不多就是将父母辈的产物,继承给自己然后自己就会合理拥有父母辈的资产和资源,在程序中也差不多我们可以通过继承的方式得到父辈的资源和资产。
3.继承的目的
其实就是从他们那里获取资产和资源然后供给己用,我们在代码中继承了上方已经编写好的我们也需要的代码的话那么我们就可以继承过来,合理合法的获得它内部的功能并且通过句点符就可以调用他内部的功能。
4.继承的操作
class 类名(父类名):
pass
4.1 我们只需要在类名后方加一个括号
4.2 在括号内填入我们所需要的父类名就好了
4.3 父类是可以同时调用多个的只需要在父类名后面跟逗号就可以填写下一个父类名
class 类名 (父类名1, 父类名2, 父类名3......):
pass
我们在调用父类时一般是从左往右开始寻找
5.继承的称谓
我们在继承的时候继承者一般叫做:子类或派生类
在被我们所继承的类叫做:父类,基类或超类
一般叫父类或子类即可
![image](https://img2022.cnblogs.com/blog/2904194/202207/2904194-20220727194212469-1545778689.png)
继承的本质
1、所有的类都继承自object类,即所有的类都是object类的子类
2、子类一旦继承父类,则可以使用父类中除私有成员外的所有内
3、子类继承父类后并没有将父类成员完全赋值到子类中,而是通过引用关系访问调用
4、子类中可以定义独有的成员属性和方法
5、子类中定义的成员和父类成员如果相同,则优先使用子类成员
6、子类如果想扩充父类的方法,可以在定义新方法的同时访问父类成员来进行代码重用
7、可以使用 [父类名.父类成员] 的格式来调用父类成员,也可以使用[super().父类成员]的 格式来调用
![image](https://img2022.cnblogs.com/blog/2904194/202207/2904194-20220727194114116-274208258.png)
不继承情况下名字查找顺序
# 1.在没有继承任何类的情况下去查找顺序
class Game: # 创建一个类
game_name = 'LOL' # 命名类
def eat_river_crab(self): # 类中加函数也就是功能
print('吃河蟹') # 额吃
game1 = Game() # 赋值
print(game1.game_name) # LOL 打印game1的值
game1.game_name = '云顶之奕' # 将game1的值修改
print(game1.game_name) # 云顶之奕 # 打印game1
print(Game.game_name) # LOL # 打印原本的Game的值
# 也就是证明我使用后面赋值的值修改并不会修改原来数据的值,因为他已经保存到他自己的对象中
![image](https://img2022.cnblogs.com/blog/2904194/202207/2904194-20220727193459719-1027778654.png)
单继承情况下名字查找顺序
1.单方面寻找
class A:
name = 'from A'
pass
class B(A):
name = 'from B'
pass
class C(B):
name = 'from C'
pass
class Myclass():
name = 'from Myclass'
pass
class Myclass2(C):
name = 'from Myclass2'
pass
obj = Myclass()
print(obj.name) # from Myclass
obj.name = '浑身就像散架一样'
print(obj.name) # # from Myclass
obj2 = Myclass2()
print(obj2.name) # 将自己的和C, B的注掉 from A
# 顺序 对象 >>> 类 >>> 父类
1.单方寻找但是自己也有值并且和第一种类重复
class A1:
def func1(self):
print('form func1')
def func2(self):
print('from func2')
def func3(self):
print('from func3')
self.func1() # obj.func1
class Myclass(A1):
def func1(self):
print('from Myclass')
obj = Myclass()
obj.func1() # from Myclass
obj.func3() # from func3,from Myclass 判断自己有没有(没有), 去父级中寻找找到了先打# 印来自func3,
# 然后往下走又是func1因为本质上其实还是obj.func1所以还是 自己的Myclass
![image](https://img2022.cnblogs.com/blog/2904194/202207/2904194-20220727194921473-815011547.png)
多继承情况下名字查找顺序
1.查找顺序内置方法mro()查看对象名的查找顺序
2.继承方式
非菱形继承(最后不会归总到一个我们自定义类上)
深度优先(每个分支都走到底 再切换)
菱形继承(最后归总到一个我们自定义类上)
广度优先(前面几个分支都不会走最后一个类 最后一个分支才会走)
3.代码
class A:
name = 'from A'
pass
class B():
name = 'from B'
pass
class C():
name = 'from C'
pass
class D(A):
# name = 'from D'
pass
class E(B):
# name = 'from E'
pass
class F(C):
# name = 'from F'
pass
class Myclass(F):
# name = 'from Myclass'
pass
obj = Myclass()
print(obj.name)
obj.name = '浑身就像散架一样'
print(obj.name)
print(Myclass.mro()) # [<class '__main__.Myclass'>, <class '__main__.F'>, <class '__main__.C'>, <class 'object'>]
print(Myclass.__bases__) # (<class '__main__.F'>,)
![image](https://img2022.cnblogs.com/blog/2904194/202207/2904194-20220727194526466-1691618966.png)
经典类与派生类
1.经典类
什么都不继承
2.新式类
继承object或则其他类
3.类型存在
经典类只有在python2中才存在就是什么东西都没有继承。
新式类在我们的python2中和3中都有但是在py2中必须自己写后面的(object)而在python3中则不需要直接已经直接优化到内部不需要再也出来也默认有。
但是还是建议写成,增加兼容性
class Myfunc(object):
pass
![image](https://img2022.cnblogs.com/blog/2904194/202207/2904194-20220727193715815-423057161.png)
派生类的概念
子类在内部写了和父类相同的代码,并且更加完善了代码扩展了其功能叫做派生。
class Person:
def __init__(self, name, age, hobby):
self.name = name
self.age = age
self.hobby = hobby
class Teacher(Person):
def __init__(self, name, age, hobby, lever):
super().__init__(name, age, hobby)
self.lever = lever
class Student(Person):
pass
t1 = Teacher('joseph', 21, 'read', 1/10)
p1 = Student('joseph', 21, 'read')
print(t1)
print(p1)
t1.__init__('joseph', 21, 'read', 1/10)
class Myclass(list):
def append(self, value):
if value == 'joseph':
print('joseph 不许过')
return
super().append(value)
object = Myclass()
object.append(520)
object.append(666)
object.append(999)
object.append('joseph') # joseph 不许过
object.append('Alice')
print(object) # [520, 666, 999, 'Alice']
![image](https://img2022.cnblogs.com/blog/2904194/202207/2904194-20220727193548533-1118033460.png)