面向对象
什么是面向对象
首先,看一看与之对应的面向过程
面向过程编程
关注的核心是过程,就是一步一步地执行步骤
优点:逻辑清晰,可以把复杂问题简单化流程化。
缺点:扩展性差,可维护性差。
使用场景:
对扩展性要求比较低的程序例如:系统内核,git
面向对象
是指一种编程思想,是编程前辈总结的经验,指导??如何编写出更好的代码。
核心是对象,程序是一系列对象的集合,??负责调度控制这些对象来交互着完成任务:
优点:扩展性,灵活性,重用性
缺点:程序的复杂度提高了,无法准确预知结果
使用场景:
对扩展性要求比较高的程序
案例1:把大象装进冰箱 面向过程: 1. 打开冰箱 2. 装入大象 3. 关闭冰箱 面向对象: 找个具备这个技能的对象 在面向对象中??的角度发生改变,从具体的操作 变成了指挥者 强调:对象不是凭空产生的,需要我们自己设计
案例2:西天取经 面向过程: 1. 准备行李 2. 准备关文 3. 关文盖章 4. ... 面向对象: 找五个对象,让他们去干 只负责调度
类和对象
这是OOP中的最核心的两个概念
类
即类型,类别,是一种抽象概念
是一系列具备相同特征和相同行为的对象的集合
对象
就是具体存在的某个事物,具备自己的特征和行为
对象就是特征和技能的结合体
类和对象的关系
类包含一系列对象
对象属于某个类
在生活中是现有对象再有类
而在程序中是先有类才有对象,
我们必须先告诉计算机这类的对象有什么特征有什么行为
总结一个结论:在使用面向对象编程时,第一步就是思考需要什么样的对象,
对象具有什么样的特征和行为,从而根据这些信息总结出需要的类型
创建类和对象
定义类的语法
class 类的名称: # 类中的内容 描述属性和技能 # 描述属性用变量 # 描述行为用函数 # 类名称的书写规范 首先是见名知意,名称是大驼峰命名法 # 驼峰就是单词首字母大写 # 大驼峰是第一个字母大写 # 小驼峰是
# 创建类的语法 class Student: pass# 创建对象的语法 调用类 即类名+括号stu = Student()print(stu)print(Student)
属性的写法:
属性可以写在类中
类中的属性,是所有对象公共的
也可以写在对象中
对象中的属性,是每个对象独有的
如果类中和对象中存在同样的属性,优先访问对象,如果没有再访问类
class Person: name = "小李" age = 20 sex = "male" p1 = Person()print(p1.name) # 小李p1 = Person()print(p1.name) # 小李# 类中应该放的是公有的属性# 私有的属性应该放在对象中
class Person: desc = "都吃饭" name = "小天才" # 这两个都是公共属性p3 = Person()p3.name = "小王" # 这个是独有属性print(p3.name) # 小王 # 如果类中和对象中存在同样的属性,优先访问对象print(p3.desc) # 都吃饭 # 如果没有,再访问类print(p3.__class__) #
属性的增删改查
# 增加属性对象变量名称,属性名称,属性值# 删除属性del 对象的变量名称.属性名称# 修改对象.属性 = 新的值# 查看属性 print(对象.__dict__) 只会访问对象中的属性 print(类,__dict__) 只会访问类中的属性 print(对象.__class__) 访问对象所在的class
初始化对象的属性
class Teacher: school = "oldboy" def __init__(self,name,age): print(self) # <__main__.Teacher object at 0x104954278> self.name = name self.age = aget1 = Teacher("jack",18)print(t1.name) # jackprint(t1) # <__main__.Teacher object at 0x104954278>
初始化方法不仅仅用于赋值
class PC: def __init__(self,kind,price,sys): self.kind = kind self.price = price self.sys = sys # 处理赋值以外的初始化操作 例如,启动BIOS啥啥的.... print("启动BIOS") print("启动系统分区") print("加载系统界面") print("启动成功....")p = PC("apple",15000,"macOS")print()
init方法
叫做初始化方法,本质上就是一个函数
特点1: 当实例化 对象时,会自动执行init方法
特点2:会自动将对象作为第一个参数传入,参数名称位self ,self可以是别的名字,但不建议改
功能:用户给对象赋初始值
对象的绑定方法
默认情况下类中的方法都是对象绑定方法
其特殊之处在于,
当使用对象调用该函数时会自动传入对象本身,作为第一个参数
当使用类名来调用时他就是一个普通函数,有几个参数就得传几个参数
对象的精髓就是将数据和处理数据的函数整合到一起
这样一来拿到一个对象就同时拿到了需要处理的数据以及处理数据的函数
class Student: school = '清华' def __init__(self,name,age): self.name = name self.age = age def say_hi(self): print('hello my name is %s my age is %s my school is %s' % (self.name,self.age,Student.school))stu1 = Student("小天",18)stu1.say_hi() # 当使用对象时,自动将自己传入Student.say_hi(stu1) # 当使用类时,要指定参数
类的绑定方法
# 类绑定方法# @classmethod # 类装饰器'''用 @classmethod 来装饰 特殊之处:不管用类还是对象调用,都会自动传入类本身,作为第一个参数 何时绑定给对象:当函数逻辑需要访问对象中的数据时 何时绑定给类:当函数逻辑需要访问类中的数据时@staticmethod 装饰成普通函数,不管谁调都一样 既不需要访问类的数据也不需要访问对象的数据'''import picklepickle # 快捷导入模块, 写上模块名,按住alt + 回车,再回车、。。会自动写在最上面(几百行代码会方便)# 类.__name__ 可以获取到类的名字
非绑定方法
或叫做静态方法,就是即不需访问类的数据,.也不需要访问对象的数据
语法:@staticmethod
不常用
将对象序列化到本地
需求:为学生类添加一个save方法,一个get方法
save是将对象存储到文件
get是从文件中获取对象
import osimport pickleimport timeclass Student: def __init__(self,name): self.name = name def say_hi(self): print("name:",self.name) def save(self): with open(self.name,"wb") as f: pickle.dump(self,f) @staticmethod def get(name): with open(name,"rb") as f: obj = pickle.load(f) return obj# stu = Student("rose")# stu.save()### stu1 = Student("jack")# stu1.save()# obj = Student.get("rose")# print(obj.name)## obj = Student.get("jack")# print(obj.name)print(Student.__name__)