零、文章目录
Python进阶01-面向对象基础
1、面向对象编程思想
(1)编程思想是什么
- 所谓的编程思想,就是人们利用计算机来解决实际问题的一种思维方式。
- 常见的编程思想有面向过程和面向对象,很多计算机语言的语法各不相同,但是它们基本的编程思想却是差不多的。
- Python是同时支持面向对象和面向过程的编程语言!
(2)面向过程的编程思想
-
传统的面向过程的编程思想总结起来就八个字——自顶向下,逐步细化!
- 将要实现的功能描述为一个从开始到结束按部就班的连续的“步骤”
- 依次逐步完成这些步骤,如果某一个步骤的难度较大,又可以将该步骤再次细化为若干个子步骤,以此类推,一直到结尾并得到我们想要的结果
-
程序的主体是函数,一个函数就是一个封装起来的模块,可以实现特定的功能,程序的各个子步骤也往往就是通过相关的函数来完成的!从而实现代码的重用与模块化编程
(3)面向对象的编程思想
- 所谓的面向对象,就是在编程的时候尽可能的去模拟现实世界!
- 在现实世界中,任何一个操作或者业务逻辑的实现都需要一个实体来完成!实体就是动作的支配者,没有实体,也就没有动作发生!
- 有动词就一定有实现这个动作的实体!
- 所谓的模拟现实世界,就是使计算机的编程语言在解决相关业务逻辑的时候,与真实的业务逻辑的发生保持一致,需要使任何一个动作的发生都存在一个支配给该动作的一个实体(主体),因为在现实世界中,任何一个功能的实现都可以看做是一个一个的实体在发挥其各自的“功能”(能力)并在内部进行协调有序的调用过程!
(4)面向对象实现报名案例
-
第一步:分析哪些动作是由哪些实体发出的
- 学生提出报名,
- 学生提供相关资料,
- 学生缴费,
- 机构收费,
- 教师分配教室,
- 班级增加学生信息
- 在整个过程中,一共有四个实体:**学生、机构、教师、班级!**在现实中的一个具体的实体,就是计算机编程中的一个对象!
-
第二步:定义这些实体,为其增加相应的属性和功能。
- 属性就是实体固有的某些特征特性信息,在面向对象的术语中,属性就是以前的变量。
- 功能就是就是实体可以完成的动作,在面向对象的术语中,功能就是封装成了函数或方法。
- 第三步:让实体去执行相应的功能或动作
- 学生提出报名
- 学生提供相关资料
- 教师登记学生信息
- 学生缴费
- 机构收费
- 教师分配教室
- 班级增加学生信息
(5)面向过程向面向对象思想迁移
- 以前写代码,首先想到的是需要实现什么功能——调用系统函数,或者自己自定义函数,然后按部就班的执行就行了!
- 以后写代码,首先想到的是应该由什么样的主体去实现什么样的功能,再把该主体的属性和功能统一的进行封装,最后才去实现各个实体的功能。
- 注意:面向对象并不是一种技术,而是一种思想,是一种解决问题的最基本的思维方式!
- 所以,面向对象的核心思想是:不仅仅是简单的将功能进行封装(封装成函数),更是对调用该功能的主体进行封装,实现某个主体拥有多个功能,在使用的过程中,先得到对应的主体,再使用主体去实现相关的功能!
(6)面向过程和面向对象的区别
- 都可以实现代码重用和模块化编程,面向对象的模块化更深,数据也更封闭和安全
- 面向对象的思维方式更加贴近现实生活,更容易解决大型的复杂的业务逻辑
- 从前期开发的角度来看,面向对象比面向过程要更复杂,但是从维护和扩展的角度来看,面向对象要远比面向过程简单!
- 面向过程的代码执行效率比面向对象高
2、面向对象基本概念
(1)面向对象基本概念
- OOA:面向对象分析
- OOD:面向对象设计
- OOP:面向对象编程
(2)对象的概念
- 对象,object,现实业务逻辑的一个动作实体就对应着OOP编程中的一个对象!
- 对象使用属性(property)保存数据!
- 对象使用方法(method)管理数据!
(3)类的概念
- 对象如何产生?又是如何规定对象的属性和方法呢?
- 答:在Python中,采用类(class)来生产对象,用类来规定对象的属性和方法!也就是说,在Python中,要想得到对象,必须先有类!
- 为什么要引入类的概念?
- 答:类本来就是对现实世界的一种模拟,在现实生活中,任何一个实体都有一个类别,类就是具有相同或相似属性和动作的一组实体的集合!所以,在Python中,对象是指现实中的一个具体的实体,而既然现实中的实体都有一个类别,所以,OOP中的对象也都应该有一个类!
(4)类的定义
-
Python3中类分为:经典类 和 新式类
- 经典类:不由任意内置类型派生出的类,称之为经典类
class 类名: 代码 ......
- 新式类
class 类名(): 代码 ......
-
类名既可以大写也可以小写,遵守一般的标识符的命名规则(以字母、数字和下划线构成,并且不能以数字开头),一般为了和方法名相区分,类名的首字母一般大写!(大驼峰法)
-
新式类创建案例如下:
'''
类是相同或相似属性和方法的一组对象的集合,是一个抽象概念。
如果想获得一个对象,首先应该创建一个类,基本语法:
class 类名(object):
# 属性 => 变量
# 方法 => 函数
注意事项:类名在Python中,一般采用大驼峰的命名法,其主要由字母、数字以及下划线,但是不能以数字开头!!!
注意事项:类在定义构成中,只是描述了一下未来这个对象所拥有的属性和方法,但是其本身并没有并调用,只有在实例化对象时其才真正执行!!!
'''
class Person(object):
# 属性
# 方法
def eat(self):
print('i can eat food!')
def run(self):
print('i can run!')
(5)类的实例化(创建对象)
- 类只是对象的一种规范,类本身基本上什么都做不了,必须利用类得到对象,这个过程就叫作类的实例化!
- 类是一个抽象概念,在定义时,其并不会真正占用计算机内存空间。但是对象是一个具体的事务,所以其要占用计算机的内存空间。
- 基本语法:
对象名 = 类名()
- 创建对象案例:
'''
类是具有相同或相似属性或方法的一组对象的集合,其是一个抽象概念。要想把其创建为具体的对象,需要经过实例化的过程。
获取对象 => 类的实例化,基本语法:
对象名称 = 类名()
产生了对象以后,则这个对象会自动拥有类中的所有公共属性和公共方法,如何调用?
答:可以通过"对象名称.属性或者对象名称.方法()"方式实现对自身属性和方法的调用
类是一个抽象概念,可以同时产生多个对象。
'''
class Person(object):
# 属性
# 方法
def eat(self):
print('i can eat food!')
def drink(self):
print('i can drink juice!')
# 类的实例化 => 产生一个甚至多个对象
p1 = Person()
p1.eat()
p1.drink()
p2 = Person()
p2.eat()
p2.drink()
(6)self
- 在类中,有一个特殊关键字self,其指向类实例化对象本身
'''
有一个问题:在我们定义类的时候,我们描述的是未来实例化对象所拥有的属性和方法,但是为什么所有的对象方法都要有一个参数self,self关键字到底代表什么含义呢?
答:在类中定义的对象方法中的self参数,与实例化产生的对象内存地址一致,所以代表两者指向了相同的内存空间。所以self
关键字就代表实例化对象本身。
简单来说:谁实例化了Person类,类中的对象方法就指向谁,self就相当于实例化对象本身!
由于self关键字在类的内部就代表对象本身,所以我们在方法的里面可以使用self调用自身的属性或方法。
'''
class Person(object):
# 属性
# 方法
def speak(self):
print(self)
# 实例化p1对象
p1 = Person()
print(p1) # <__main__.Person object at 0x00000184FF8FD3D0>
p1.speak() # <__main__.Person object at 0x00000184FF8FD3D0>
p2 = Person()
print(p2) # <__main__.Person object at 0x00000184FF8FD400>
p2.speak() # <__main__.Person object at 0x00000184FF8FD400>
3、添加和获取对象属性
(1)属性是什么
- 属性即是特征,比如:人的姓名、年龄、身高、体重…都是对象的属性。
- 对象属性既可以在类外面添加和获取,也能在类里面添加和获取。
(2)类外部添加对象属性
- 基本语法:对象名.属性名 = 值
(3)类外面获取对象属性
- 基本语法:对象名.属性名
'''
在Python中,每个对象一般都是由两部分内容组成的:① 属性 ② 方法
我们既可以在类的内部也可以在类的外部为其对象添加属性或获得属性
在类的外部如何添加属性:
对象名称.属性 = 属性值,如果属性值是一个字符串类型,还需要使用引号引起来!
在类的外部如何获得属性:
print(对象名称.属性)
'''
class Person(object):
# 属性
# 方法
def eat(self):
print('i can eat food!')
def drink(self):
print('i can drink juice!')
# 实例化产生对象
p1 = Person()
# 在类外部为p1对象添加属性
p1.name = '小明'
p1.age = 23
# 在类外部获得p1对象的属性
print(p1.name)
print(p1.age)
p1.eat()
p1.drink()
p2 = Person()
p2.name = '小美'
p2.age = 19
print(p2.name)
print(p2.age)
(4)类里面获取对象属性
- 基本语法:self.属性名
'''
刚才为大家介绍过,可以在类的外部为对象添加动态属性,添加完成后,我们是否可以在类的内部对其进行获取呢?
在类的内部,我们可以通过对象方法中的self关键字来实现对自身属性和方法的调用
① self指向谁?谁实例化这个类,self就指向谁(对象)
② self有何作用?可以通过self.属性或者self.方法()形式来实现对自身属性或方法的调用
'''
# 1、定义一个类
class Person(object):
# 2、定义属性
# 3、定义方法
def eat(self):
pass
def print_info(self):
print(f'姓名:{self.name}')
print(f'年龄:{self.age}')
print(f'地址:{self.address}')
# 4、实例化Person类产生对象
p1 = Person()
# 5、动态为对象添加属性
p1.name = '小明'
p1.age = 23
p1.address = '广州市天河区'
# 6、通过p1对象,调用自身的print_info方法
p1.print_info()
4、魔术方法
(1)魔术方法是什么
- 在Python中,
__xxx__()
的函数叫做魔法方法,指的是具有特殊功能的函数。
(2)__init__()
方法
- 作用:实例化对象时,连带其中的参数,会一并传给
__init__()
函数自动并执行它。__init__()
函数的参数列表会在开头多出一项,它永远指代新建的那个实例对象,Python语法要求这个参数必须要有,名称为self。 __init__()
方法,在创建一个对象时默认被调用,不需要手动调用。__init__(self)
中的self参数,不需要开发者传递,python解释器会自动把当前的对象引用传递过去。
'''
__init__() :初始化方法(在其他编程语言中,也称之为构造函数),顾名思义,其主要的作用就是进行一些初始化工作
实际工作场景:
① 在类的定义,用于描述对象未来所拥有的公共属性
② 还可以用于进行系统的初始化工作 => 比如文件操作中的打开文件,数据库操作中的连接数据库等等
魔术方法:
① 在什么情况下,__init__()会被触发(调用),当实例化对象时,__init__()方法会自动被触发
实例化多少次,__init__()方法就会被调用多少次
② 在实际工作中,主要用于公共属性的初始化或者项目的初始化工作
举个栗子:让我们Person实例化对象自动拥有name、age以及address三个公共属性
'''
class Person(object):
# 1、描述未来对象所拥有的公共属性
def __init__(self):
self.name = '孙悟空'
self.age = 50
self.address = '花果山水帘洞'
# 2、描述未来对象所拥有的公共方法
def eat(self):
print('i can eat food!')
def drink(self):
print('i can drink juice!')
# 1、实例化对象p1
p1 = Person()
print(p1.name)
print(p1.age)
print(p1.address)
p2 = Person()
print(p2.name)
print(p2.age)
print(p2.address)
(3)带参数的__init__()
方法
- 如果需要在对象创建的时候传入参数,需要使用带参数的
__init__()
'''
遗留问题:虽然我们可以通过__init__()魔术方法为每一个对象添加三个属性name、age以及address,但是每个实例化对象
所拥有的属性值都是一样的,如何解决以上问题。
答:通过__init__()方法进行传递参数
'''
class Person(object):
# 定义公共属性
def __init__(self, name, age, address):
# self => 对象本身
# self.name属性 = 参数,即使属性与参数同名也没有任何影响
self.name = name
self.age = age
self.address = address
# 定义公共方法
def speak(self):
# self还可以调用自身属性或方法
print(f'我的名字:{self.name},年龄:{self.age},来自:{self.address}')
# 实例化对象
p1 = Person('孙悟空', 23, '花果山水帘洞')
print(p1.name)
print(p1.age)
print(p1.address)
p2 = Person('猪八戒', 22, '高老庄')
print(p2.name)
print(p2.age)
print(p2.address)
(4)__str__()
方法
- 当使用print输出对象的时候,默认打印对象的内存地址。如果类定义了
__str__
方法,那么就会打印从在这个方法中return 的数据。
'''
掌握一个魔术方法有两个地方:① 在什么情况下会被触发 ② 在实际工作中,__str__()方法有何作用
__str__() :① 当我们使用print()直接打印对象时,__str__()魔术方法会自动被触发
② 当我们需要打印输出某个对象的信息时,一般都可以定义__str__()魔术方法
注意事项:__str__(),必须返回字符串类型的数据,否则会直接报错。
需求:定义一个汽车类,类实例化对象必须要拥有哪些属性?brand品牌、model型号、color颜色
当我们打印这个汽车类对象时,要求输出这辆车的相关信息
'''
# 1、定义一个类
class Car(object):
# 2、为未来对象添加公共属性
def __init__(self, brand, model, color):
self.brand = brand
self.model = model
self.color = color
# 3、定义一个魔术方法__str__()
def __str__(self):
return f'汽车品牌:{self.brand},汽车型号:{self.model},汽车颜色:{self.color}'
# 4、实例Car类,产生一个对象
bmw = Car('宝马', '320', '黑色')
print(bmw)# 汽车品牌:宝马,汽车型号:320,汽车颜色:黑色
benz = Car('奔驰', '600', '灰色')
print(benz)# 汽车品牌:奔驰,汽车型号:600,汽车颜色:灰色
(5)__del__()
方法
- 当删除对象时,python解释器也会默认调用
__del__()
方法。
'''
① 这个魔术方法在什么情况下被触发 ② 在实际工作中,哪里可以使用到__del__方法
__del__() : 在Python中,其被称之为删除方法(在其他编程语言中,也称之为析构方法)
__init__() :构造方法,项目初始化
__del__() :析构方法,项目清理或项目收尾
__del__()当对象被删除时会自动被触发 => ① 手工del 对象 ② 当程序执行结束,内存开始清理对象时
在实际工作中,__del__()方法主要用于清除对象或者实现项目清理工作,如关闭文件,关闭数据库连接
f = open()
f.read()
f.write()
f.close()
'''
class Person(object):
# 1、定义公共属性
def __init__(self, name, age):
self.name = name
self.age = age
# 2、定义一个__del__()魔术方法
def __del__(self):
print('当del 对象时,此魔术方法会自动被触发!')
# 3、实例化对象
p1 = Person('白骨精', 22)
# 4、手工删除p1对象
del p1 #当del 对象时,此魔术方法会自动被触发!
5、面向对象案例
(1)学生成绩打印
- 需求:定义学员信息类,包含姓名、成绩属性,定义成绩打印方法(90分及以上显示优秀,80分及以上显示良好,70分及以上显示中等,60分及以上显示合格,60分以下显示不及格)
'''
案例1:定义学员信息类,包含姓名、成绩属性,定义成绩打印方法(90分及以上显示优秀,80分及以上显示良好,70分及以上显示中等,60分及以上显示合格,60分以下显示不及格)
记住:在实际工作中,为了保证数据的安全性,一般不建议在类外部直接调用自身属性,如果想调用自身属性都是通过对应的方法
实现的!
'''
class Student(object):
# 为未来实例化对象定义公共属性
def __init__(self, name, score):
self.name = name
self.score = score
# 为未来实例化对象定义公共方法
def print_grade(self):
if self.score >= 90:
print(f'{self.name}成绩为{self.score}分,优秀!')
elif self.score >= 80: # 隐藏条件 80 <= score < 90
print(f'{self.name}成绩为{self.score}分,良好!')
elif self.score >= 70:
print(f'{self.name}成绩为{self.score}分,中等!')
elif self.score >= 60:
print(f'{self.name}成绩为{self.score}分,合格!')
else:
print((f'{self.name}成绩为{self.score}分,不及格!'))
s1 = Student('Tom', 98)
s1.print_grade()
s2 = Student('Jennifer', 59)
s2.print_grade()
(2)小明爱跑步
- 需求:小明体重75.0公斤,小明每次跑步会减掉0.1公斤,小明每次吃东西体重增加0.2公斤分析:
- ① 对象:小明② 属性:姓名、体重③ 方法:跑步、吃东西
'''
案例2:小明体重75.0公斤,小明每次跑步会减掉0.10公斤,小明每次吃东西体重增加0.20公斤。
分析:① 对象:小明 => 人类别 ② 属性:姓名、体重 ③ 方法:跑步、吃东西 ④ 添加一个打印方法,输出自身信息
'''
class Person(object):
# 1、定义对象自身属性
def __init__(self, name, weight):
self.name = name
self.weight = weight
# 2、定义对象自身方法
def run(self):
# 跑步可以减少自身的体重属性
self.weight -= 0.1
def eat(self):
# 吃东西可以增加自身的体重属性
self.weight += 0.2
# 3、定义一个__str__魔术方法,打印对象自身信息
def __str__(self):
return f'我的名字叫{self.name},当前体重{self.weight:.2f}kg!'
p1 = Person('小明', 75)
print(p1)
# 小明爱跑步
p1.run()
print(p1)
p1.eat()
print(p1)