Python面对对象(中)
python面向对象
-
动静态方法
-
面对对象值继承理论
-
继承基本操作
-
对象查找名字的顺序
-
继承本质
-
基于继承的派生方法
-
动静态方法
方法也就是函数,什么叫动静态呢,就是指自己传参的就是动态,需要手动传参的就是静态,这些方法又是如何被定义的呢,主要方式有三种
1. 动态方法
class Student:
school_name = '摆烂大学'
# 1. 类中直接定义函数,默认绑定给对象,类调用有几个参数传几个,对象调用的第一个参数就是对象自身
def func1(self):
print('看看谁最能摆烂,很棒')
obj = Student()
# 1. 绑定给对象的方法
obj.func1()
# 类调用
Student.func1(123)
结果:
看看谁最能摆烂,很棒
看看谁最能摆烂,很棒
"""
1. 第一种在定义方法时 在类中直接定义,默认是绑定给对象的,也就是说使用对象调用时会将对象名当做第一个参数传入,所以这里第一步调用的时候不需要额外的参数
2. 而在我们使用类调用这个方法时,有几个参数就需要写几个,需要对应传入的参数并不会有什么特殊的作用仅仅是占位传参
"""
2. 动态方法
class Student:
school_name = '摆烂大学'
# 2. 被@classmethod修饰的函数,默认绑定给类,类调用的第一个参数就是类自身,对象也可以调用并且会自动将产生该对象的类当做第一个参数传入
@classmethod
def func2(cls):
print('猜猜我是干嘛滴', cls)
obj = Student()
# 2. 绑定给类的方法
Student.func2()
obj.func2()
猜猜我是干嘛滴 <class '__main__.Student'>
猜猜我是干嘛滴 <class '__main__.Student'>
"""
1. 第二种定义方法时使用自带的@classmethod装饰器,被这个装饰器装饰的函数 ,,与上一个不同的是默认会绑定给类,也就是说类在调用时不传入参数会将当前类的名字传入,也就是这里使用的Student.func2()
2. 这种方式对象也是可以调用的,同样在对象调用时,会将当前产生对象的类名当做参数自动传入
"""
3. 静态方法
class Student:
school_name = '摆烂大学'
# 3. 普普通通的函数 无论是类还是对象的调用,都必须自己手动传参
@staticmethod
def func3(a):
print('猜猜我又是干什么滴', a)
obj = Student()
Student.func3(123)
obj.func3(321)
猜猜我又是干什么滴 123
猜猜我又是干什么滴 321
"""
1. 静态方法的定义同样需要使用装饰器,在定义时使用@staticmethod,被这个装饰器装饰的方法,在调用的过程中需要自己手动传入参数,
2. 类调用和对象调用都需要手动传入参数,传入的参数是什么就是什么
3. 这也就是和什么两者最大的区别
"""
- 面向对象继承概念
三大核心 :封装 继承 多态
三者中 继承的实际操作较多,封装 和 多态 比较抽象
- 继承的概念
在编程中继承的概念也是和现实世界的概念差不多
-
不继承
没有任何继承状态,自己就是自己 -
单继承
现实中认了一个干爹,他的所有资源都可以唯你所用 -
多继承 (相当于“吕布行为”)
这个就很牛皮了,相当于认了一群干爹,他们所有的资源你都可以用,超级牛皮
上述是现实时间中的概念,编程中 单继承和多继承的概念如下
1. 单继承
类A继承类B 或者 类A继承类B 类B继承类C
2. 多继承
类A继承类B继承,类A又继承类C
继承其他的类,也被称为 子类 派生类
被继承的类,被称为 父类,基类,超类
- 继承的本质
- 对象:数据与功能的结合体
- 类(子类): 多个对象相同数据和功能的结合体
- 父类: 多给类(子类)相同数据和功能的结合体
类与父类的本质都是为了节省代码
从继承的角度来说,继承的本质应该分为两部分- 抽象:将多个类相同的东西抽出去形成一个新的类
- 继承:将多个类继承刚刚抽取出来的新的类
- 名称的查找顺序
- 不继承
对象查找名字的顺序
- 先从自己的名称空间中查询
- 再去产生该对象的类中查询
- 如果类中没有,则直接报错
查找顺序为 :对象自身 > 产生对象的类
- 单继承
查找顺序为:对象自身 > 产生对象的类 > 父类
强调: 对象的名字,永远从对象自身开始一步一步查找
如果类中的函数有self.名字的时候 必须搞清楚self指的是哪个对象
- 多继承
多继承分为两种
- 菱形继承
广度优先,最后才会找闭环的阶段- 非菱形继承
深度优先,从左到右每条道走到完为止
建议直接使用mro()方法可以直接获取名字的查找顺序
查找顺序为: 对象自身 > 产生对象的类 > 父类(从左往右)
- 经典类与新式类
- 经典类: 不继承object或者其子类的类
- 新式类: 继承object或者其子类的类
在python2中有两种类的区分
python3中只有新式类(所有类默认继承object)
如果在写项目时需要写的更加兼容可以采用下列写法
class Student(object):pass
- 派生方法
当继承父类之后,在调用父类的方法时,向添加一些特定的功能可以使用派生的方法
1. 演示代码-
class Person:
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
class Student(Person):
def __init__(self, name, age, gender, sid):
super().__init__(name, age, gender)
self.sid = sid
class Teacher(Person):
def __init__(self, name, age, gender, level):
super().__init__(name, age, gender)
self.level = level
stu1 = Student('wesley', 18, 'male', 666)
print(stu1.__dict__)
stu2 = Student('andy', 48, 'female', 90)
print(stu2.__dict__)
{'name': 'wesley', 'age': 18, 'gender': 'male', 'sid': 666}
{'name': 'andy', 'age': 48, 'gender': 'female', 'sid': 90}
"""
上述代码就是继承Person这个类之后调用方法时发现需要的信息不一样,所有使用了派生方法spuer的方式调用父类的方法,再新增加了新的功能
"""
2. 代码演示2,静止列表中的append添加'wesley'
class Mylist(list):
def append(self, values):
if values == 'wesley':
print('🈲止wesley尾部追加')
return
super().append(values)
obj = Mylist()
obj.append(111)
obj.append(222)
obj.append(333)
obj.append('wesley')
print(obj)
结果
🈲止wesley尾部追加
[111, 222, 333]

浙公网安备 33010602011771号