python面向对象——OOP编程
编程思维方式:
面向过程
面向过程方法
1、把完成某一个需求的所有步骤从头到尾逐步实现
2、根据开发需求,将某些功能独立的代码封装成一个个函数
3、最后完成的代码,就是顺序地调用不同的函数
特点:
1、注重步骤和过程,不注重分工
2、如果需求复杂,代码会变得很复杂
3、开发复杂项目,没有固定的套路,开发难度很大
适合操作系统、数据库服务器等固定套路的项目
面向对象
面向对象方法
1、在完成某个需求前,首先确定职责——要做的事情(方法)
2、根据职责确定不同的对象,在对象内部封装不同的方法(多个)
3、最后完成的代码,就是顺序地让不同的对象调用不同的方法。
特点:
1、注重对象和职责,不同的对象承担不同的职责
2、更加适合应对负责的需求变化,是专门应对负责项目开发,提供的固定套路
3、需要在面向过程基础上实现的。
面向对象详解
-
类:是对一群具有相同特征或者行为的事物的一个统称,是抽象的,不能直接使用。
- 特征被称为属性 ——变量——(飞机的长宽高、颜色)
- 行为被称为方法——函数——(飞机飞翔、滑翔、翻转)
- 相当于飞机图纸
-
对象:对象是由类创造出来的一个具体存在,可以直接使用
- 由哪个类创造的对象,就拥有在哪个类中定义的属性和方法
- 相当于通过飞机图纸制造的飞机
-
类和对象的关系
- 类是模板,对象是根据这个模板创建出来的,应该先有类,再有对象
- 类只有一个,而对象可以有很多个,不同对象之间的属性可能会各不相同
- 类中定义了什么属性和方法,对象中就有什么属性和方法,不会多也不会少
类的设计
内置函数dir()
dir()内置函数能够查看对象内的所有属性及方法。
常见的魔法方法:
__del__方法
# 当前程序退出时,对象从内存空间销毁前自动调用__del__方法
# 作用:清楚资源的操作
class Cat:
"""猫类"""
def __init__(self,name):
"""初始化方法"""
self.name = name
def eat(self):
"""吃方法"""
print("%s 吃鱼干" % self.name)
def __del__(self):
"""删除魔法方法"""
print("当前程序退出,对象从内存空间销毁前自动调用")
print("清楚当前资源操作")
tom = Cat("汤姆")
tom.eat()
# 注意:__del__在程序退出前自动调用,也可以手动调用
使用,可以把文件关闭写入del方法中,可以避免造成写入错误时,没有关必文件,造成资源浪费
__str__方法
str方法在打印对象时,自动调用
__str__方法必须要有返回值,并且只能返回字符串
类的定义格式
语法格式如下:
class 类名:
def 方法1(self,参数列表):
pass
def 方法2(self,参数列表):
pass
定义只含方法的类
class Person:
def run(self):
print("跑方法")
def eat(self,food):
print("吃方法,吃%s" % food)
def sleep(self):
print("睡觉方法")
xiao_ming = Person()
# self参数不需要我们传递,由python解释器自动传递
xiao_ming.run()
xiao_ming.eat("apple")
xiao_ming.sleep()
函数与方法的区别
1、相同点:都是封装代码的整体,实现某个功能的工具
2、不同点:
①定义的位置不同:函数定义在类外部,方法定义在类内部
②参数不同:函数没有self参数,而方法有self参数
③调用方式不同:函数名(参数),对象名.方法名(参数)
方法的调用顺序与多个对象的引用关系
调用顺序
1、定义类模板时,python解释器会进入类模板内部扫描一次,定义方法,不会进入方法内部执行代码,类模板只会被初始化一次
2、当使用类模板创建对象,通过对象名.方法名()调用方法时,才会进入方法内部执行代码
3、方法中的代码执行完后,回到调用方法的地方,继续向下执行
一个对象的引用关系
多个对象的引用关系
# 探究 类 中方法的调用顺序
class Cat:
"""
猫类
"""
def eat(self):
"""
吃方法
"""
print("小猫爱吃鱼")
def drink(self):
"""
喝方法
"""
print("小猫要喝水")
print(Cat())
cat = Cat()
print(cat)
tom = Cat()
print(tom)
self参数
self参数保存当前对象的引用地址
class Cat:
"""猫类"""
def eat(self):
"""吃方法"""
print("eat()方法的self:",self)
print("小猫爱吃鱼")
def drink(self,water):
"""喝方法"""
print("drink()方法的self:", self)
print("小猫要喝%s" % water)
tom = Cat()
print("tom:",tom)
tom.eat()
print("-"*50)
lazy_cat = Cat()
print("lazy_cat:",lazy_cat)
lazy_cat.eat()
给对象添加属性
在类的外部给对象添加属性
使用方式:
# 给对象添加属性
# 1、在类的外部给对象添加属性
# 对象名.属性名 = 属性值
class Cat:
"""猫类"""
def eat(self):
"""吃方法"""
# 利用self在类的内部访问属性
print("%s 爱吃鱼" % self.name)
self.drink("colo")
def drink(self, water):
"""喝方法"""
print("%s要喝%s" % (self.name,water))
tom = Cat()
# 在类的外部添加属性
tom.name = "汤姆"
# 在类的外部访问属性
# 对象名.属性名
print(tom.name)
# 通过self.属性名,在类的内部访问属性或方法
tom.eat()
出现的问题:
在类的外部给对象添加属性,如果先访问方法,后添加属性,可能会造成属性找不到的错误
因此不推荐使用
在类的内部给对象添加属性
初始化方法__init__()
- 当使用 类名() 创建对象时,会自动执行以下操作:
- 1、为对象在内存中分配空间——创建对象
- 2、为对象的属性设置初始值——初始化方法(init)
- 这个初始化方法就是__init__方法
- __init__方法会在使用类模板创建对象时自动调用
class Cat:
"""
猫类
"""
def __init__(self):
#初始化方法
#主要用于初始化属性数据
#初始化方法在使用类模板创建对象时自动调用
print("初始化属性数据")
def eat(self):
"""
吃方法
"""
print("小猫爱吃鱼")
tom = Cat()
实现在类内部添加属性
class Cat:
"""猫类 """
def __init__(self):
#初始化方法
print("初始化属性数据")
# 在类内部添加属性,通过self.属性名 = 属性初始值
self.name = "汤姆猫"
print("自动调用添加属性")
def eat(self):
"""吃方法"""
print("小猫爱吃鱼")
tom = Cat()
print(tom.name)
改造初始化方法——初始化的同时设置初始值
1、把希望设置的属性值,定义成__init__方法的参数
2、在方法内部使用 self.属性 = 形参,接受外部传递的参数
3、在创建对象时,使用类名(属性1,属性2.。。)调用
class Cat:
"""猫类 """
def __init__(self,new_name):
#初始化方法
self.name = new_name
def eat(self):
"""吃方法"""
print("%s爱吃鱼" % self.name)
tom = Cat("汤姆")
tom.eat()
lazy_cat = Cat("波斯猫")
lazy_cat.eat()