前言
本文主要介绍了面向对象的基础内容(类与对象)和一些常见的魔法方法。下一篇:面向对象进阶(继承、封装、多态)点这!!!
一、面向对象
面向对象和面向过程
面向对象和面向过程都是解决问题的一种思路,一种方式 # 吃火锅 # 第一种方式:在家吃 --- 面向过程 买菜-->洗菜-->摆盘-->下菜-->吃-->洗锅-->扔垃圾 # 第二种方式:去店里吃 --- 面向对象 扫码-->吃 # 面向对象建立在面向过程的基础上 1、面向对象就是:把数据和对数据的操作封装在一起组成类,通过类来创建对象,通过对象之间的交互来实现程序的功能。 2、面向对象落地需要使用 “类” 和 “对象”
优缺点
面向对象:核心就是对象,上帝式思维 优点:上帝眼里万物皆存在,代码效率高 缺点:无法及时准确的发现问题并解决 面向过程:核心就是过程,流水线式思维 优点:过程中及时发现并解决问题 缺点:大量的代码堆叠只为了实现一个简单的功能,过程中出现问题,接下来的操作无法正常执行
二、类与对象
类与对象的区别:类就是创建对象的模板
1.类
1.1 类的介绍
人类 将具有共同特征和行为的事物进行抽象,抽象出一个类 对象 类中具体的一个实例-->张三 李四 王五 类是抽象的,在使用的时候通常会找到这个类的一个具体的存在,使用这个具体的存在。一个类可以找到多个对象
1.2 类的构成
类(Class) 由3个部分构成 - 类的名称:类名 - 类的属性:一组数据 - 类的方法:类提供的可以进行一定操作的方法 (行为) 特征即属性(数据) 行为即方法(对数据的操作) 人类设计,只关心3样东西: - 事物名称(类名):人(Person) - 属性:身高(height)、年龄(age) - 方法(行为/功能):跑(run)、打架(fight)
1.3 类的抽象
方法:一般名词都是类(名词提炼法) **<1> 坦克发射3颗炮弹轰掉了2架飞机** - 坦克--》可以抽象成 类 - 炮弹--》可以抽象成类 - 飞机-》可以抽象成类
1.4 类的定义
# 定义类 # 语法格式: # class 类名(要继承的父类): # 属性 # 方法 # 1.类名首字母大写,推荐使用大驼峰命名法(每一个单词首字母都大写,其余字母都小写) # 2.要继承的父类可有可无,如果没有要继承的父类,类名后的()可以省略 # 3.object是所有类的顶级父类 # 根据是否继承object对类进行区分 # python2: # 新式类:继承了object类 # 经典类:也称之为旧式类,没有object类 # python3: # 没有经典类与新式类区分,所有的类都是新式类; class Person(object): class Person(): class Person: pass
1.5 定义实例方法
# 定义英雄类 class Hero: # 在类中编写方法-->以函数的形式编写方法 # self-->实例对象本身 # 编写的方法称之为:实例方法 def run(self): print("会跑")
2.对象
2.1 对象的介绍
某一个具体事物的存在 ,在现实世界中可以是看得见摸得着的。可以是直接使用的。
2.2 对象的定义
# 让实例对象调用实例方法 对象名.方法名() luban.run() anqila.run()
2.3 对象调用方法
# 让实例对象调用实例方法 对象名.方法名() luban.run() anqila.run()
2.4 给对象增加属性并获取
# 给实例对象增加实例属性 对象名.属性名 = 属性值 luban.name = "鲁班" luban.gender = "男" luban.age = 6 anqila.name = "安其拉" anqila.gender = "女" anqila.age = 10 # 获取实例对象的实例属性 print(对象名.属性名) print(luban.age) print(anqila.gender)
2.5 在实例方法中使用实例属性
# 定义英雄类 class Hero: def info(self): # 想要在实例方法中使用实例属性 self.属性名 # self--》实例对象本身 # 如果luban对象调用info方法,self-->luban # 如果anqila对象调用info方法,self-->anqila print(f"这个英雄的姓名是{self.name},年龄是{self.age},性别为{self.gender}")
三、魔法方法
概念
魔法方法:
表象:以__开头__结尾的方法称之为魔法方法
本质:不需要手动调用,会在特定的情况下自动被调用
_ init _()
# 定义一个鱼类 Fish class Fish: # 魔法方法__init__:初始化方法 # 作用:给实例对象增加实例属性 # 调用:对象一旦创建成功会立马调用init # init方法的实参需要在 类名(实参) 的时候传递 def __init__(self,name,price,weight): # 一个类有多个对象,想要给对象设置属性,不能直接写对象名,使用self代替 # 每一个对象的属性值都不固定,属性值不能直接写死,通过传参的形式指定 # 设置实例属性 对象名.属性名 = 属性值 self.name = name self.price = price self.weight = weight # 类中定义方法:计算鱼的总价 "当前这个xxx鱼,xxx元一斤,xxx斤总共需要花费xxx元" # 实例方法-->以函数的形式定义 # self--》实例对象本身 def info(self): # 在实例方法中使用实例属性 self.属性名 print(f"当前这个{self.name},{self.price}元一斤,{self.weight}斤总共需要花费{self.price * self.weight}元") # 实例化两条鱼 鲤鱼 鲫鱼…… 对象名 = 类名() liyu = Fish("鲤鱼",5.6,9) jiyu = Fish("鲫鱼",4,7) # 实例对象调用实例方法 对象名.方法名() liyu.info() jiyu.info()
_ new _()
# 定义一个鱼类 Fish class Fish: # 魔法方法__init__:初始化方法 # 作用:给实例对象增加实例属性 # 调用:对象一旦创建成功会立马调用init # init方法的实参需要在 类名(实参) 的时候传递 def __init__(self,name,price,weight): # 一个类有多个对象,想要给对象设置属性,不能直接写对象名,使用self代替 # 每一个对象的属性值都不固定,属性值不能直接写死,通过传参的形式指定 # 设置实例属性 对象名.属性名 = 属性值 self.name = name self.price = price self.weight = weight print("这是我的init方法") # 魔法方法__new__ # cls-->类对象本身 # 结论:new在init前被执行 # 作用:创建对象 # 调用:在实例化对象的时候被调用 def __new__(cls, *args, **kwargs): # __new__方法必须至少有cls参数 # 在自己实现__new__方法时注意:new的功能:返回父类__new__出来的实例 # 没有自己继承的父类,可以使用顶级父类object print("这是我的new方法") return object.__new__(cls) # 实例化两条鱼 鲤鱼 鲫鱼…… 对象名 = 类名() liyu = Fish("鲤鱼",5.6,9) jiyu = Fish("鲫鱼",4,7) # 注意: 1.后续编写类的时候不需要重写new方法,new方法在底层编写好了 2.当前这个案例编写new,为了理解new鱼init区别,谁先执行谁后执行,研究功能 3.new功能:只有返回父类__new__出来的实例,才能将对象创建成功(给对象开辟内存空间) 4.先执行__new__再执行__init__ 5.单例模式、工厂模式需要重写new方法 `__new__`至少要有一个参数cls,代表要实例化的类,此参数在实例化时由Python解释器自动提供 `__new__`必须要有返回值,返回实例化出来的实例,这点在自己实现`__new__`时要特别注意,可以return父类`__new__`出来的实例,或者直接是object的`__new__`出来的实例 `__init__`有一个参数self,就是这个`__new__`返回的实例,`__init__`在`__new__`的基础上可以完成一些其它初始化的动作,`__init__`不需要返回值 我们可以将类比作制造商,`__new__`方法就是前期的原材料购买环节,`__init__`方法就是在有原材料的基础上,加工,初始化商品环节
_ str _()
# 定义一个鱼类 Fish class Fish: # 魔法方法__init__:初始化方法 # 作用:给实例对象增加实例属性 # 调用:对象一旦创建成功会立马调用init # init方法的实参需要在 类名(实参) 的时候传递 def __init__(self,name,price,weight): # 一个类有多个对象,想要给对象设置属性,不能直接写对象名,使用self代替 # 每一个对象的属性值都不固定,属性值不能直接写死,通过传参的形式指定 # 设置实例属性 对象名.属性名 = 属性值 self.name = name self.price = price self.weight = weight print("这是我的init方法") # 魔法方法__str__ # 调用:print(对象) # 功能:返回一个字符串 # 作用:返回对象的描述信息 def __str__(self): return f"当前这个{self.name},{self.price}元一斤,{self.weight}斤总共需要花费{self.price * self.weight}元" # 实例化两条鱼 鲤鱼 鲫鱼…… 对象名 = 类名() liyu = Fish("鲤鱼",5.6,9) jiyu = Fish("鲫鱼",4,7) # 打印对象 # 如果不重写str方法,打印对象时会得到对象的内存地址 print(liyu) print(jiyu)
_ del _()
# 定义一个鱼类 Fish class Fish: # 魔法方法__del__ # 调用:当对象要被删除时调用 def __del__(self): print(f"{self.name}被删除") # 实例化两条鱼 鲤鱼 鲫鱼…… 对象名 = 类名() liyu = Fish() del liyu # 删除对象前调用del jiyu = Fish() # 对象及类中没有再需要使用对象的地方了-->对象无用-->触发垃圾回收机制-->对象会被作为垃圾进行销毁 # 对象在被真正删除之前调用del