一、面向对象的概念:
-
概念:面向对象是基于万物皆对象这个哲学观点。在Python中,一切皆对象
-
说明
案例:我想要吃大盘鸡面向过程 面向对象 1.自己去买菜 1.委托一个会砍价的人帮忙去买菜 2.自己择菜 2.委托一个临时工帮忙择菜 3.自己做菜 3.委托一个厨师帮忙做菜 4.自己开始吃 4.自己开始吃 -
面向过程
- 在生活案例中:
一种看待问题的思维方式,在思考问题的时候,着眼于问题是怎样一步一步解决的,然后亲自去解决问题 - 在程序中:
代码从上而下顺序执行,各模块之间的关系尽可能简单,在功能上相对独立,每一模块内部均是由顺序、选择和循环三种基本结构组成,其模块化实现的具体方法是使用子程序,程序流程在写程序时就已决定。
- 在生活案例中:
-
面向对象
-
在生活案例中:
也是一种看待问题的思维方式,着眼于找到【一个具有特殊功能的具体个体,然后委托这个个体去做某件事情】,我们把这个个体就叫做对象,一切皆对象,是一种更符合人类思考习惯的思想【懒人思想】,好处:可以将复杂的事情简单化,将程序员从执行者角度转换成了指挥者角度。 -
在程序中:
把数据及对数据的操作方法放在一起,作为一个相互依存的整体——对象
1》对同类对象抽象出其共性,形成类
2》类中的大多数数据,只能用本类的方法进行处理
3》类通过一个简单的外部接口与外界发生关系,对象与对象之间通过消息进行通信
4》程序流程由用户在使用中决定
5》使用面向对象进行开发,先要去找具有所需功能的对象,如果该对象不存在,那么创建一个具有该功能的对象
注意:面向对象只是一种思想,并不是一门编程语言,也不会绑定编程语言
-
-
面向过程和面向对象的优缺点【面试题】
-
面向过程:
- 优点:性能比面向对象高,比如单片机、嵌入式开发等一般采用面向过程开发,因为性能是最重要的因素
- 缺点:没有面向对象易维护,易复用,易扩展,开销比较大,比较消耗资源
-
面向对象:
- 优点:易维护,易复用,易扩展【由于面向对象有封装,继承,多态的特性,可以设计出低耦合的系统,使得系统更加灵活,更加易于维护】
- 缺点:性能比面向过程低
-
-
举例:
狗吃屎:面向对象【狗和屎是两个对象,这句话更强调对象】
吃狗屎:面向过程【这句话更强调过程】
二、类和对象的概念:
- 概念:
- 类:一个具有特殊功能的实体的集合【群体】,是抽象的
- 对象:在一个类中,一个具有特殊功能的实体,能够帮忙解决特定的问题【对象也被称为实例】,是具体的。
- 两者之间的关系:类用于描述某一类对象的共同特征,而对象则是类的具体存在
- 先有类还是现有对象:这个问题类似于先有鸡还是现有鸡蛋,怎么说都在理。
- 举例:
- 人(类):张三、李四、王麻子···(对象)
- 快递 (类):顺丰、圆通、申通、韵达···(对象)
- 说明:类也是一种数据类型,只不过是自定义的,跟所学过int,str,bool等类似。用类创建对象相当于定义一个类的变量
- 类的定义和对象的创建:
- a.Python中使用class关键字定义类
- b.类名只要是一个合法的标识符即可,但是要求:遵循大驼峰命名法 ,如:KeyError,ValueError,NameError,IndexError…….
- c.尽量使用单个或多个有意义的单词连接而成
- d.通过缩进来体现类体的存在
- e.类体一般包含两部分内容:对类的特征描述和行为描述
- 创建语法:将函数定义中的def换为class,函数名换为类名(类名遵循大驼峰命名),将函数体换成类体即可。
- 类的设计:
- 事物名称:类名
- 举例:人类(Person)
- 特征:名词(用变量表示)
- 举例:heigh、name、age
- 行为:动词(用函数表示)
- 举例:run、fight
- 说明:初期学习通过提炼动名词进行类的提取
- 类中成员函数的定义
- 动态绑定属性和限制绑定
- 类中多个对象共同的特征:变量,也被称为属性
- 通过动态绑定的属性被称为对象属性或实例属性
- 事物名称:类名
'''
类和对象
'''
#1、理解类是一种数据类型
num = 10 # 定义变量-----》创建对象
print(type(num)) # <class 'int'>
# 数据类型int----->类
# NameError/ValueError...:类
a = NameError()
print(type(a)) # <class 'NameError'>
# int是一种数据类型,本质是一个类,所以自定义的类也可以当做数据类型使用
# 通过类创建对象/通过类实例化对象:定义一个指定类的变量
#=================================================================
#2、类的定义和对象的创建
# 一、类的定义
# 1.基本语法
# 类的声明和实现
class Func():
pass # 类体
print(Func) # 自定义类:<class '__main__.Func'>
a = Func() # 创建Func的对象a
print("*" * 50)
# 2.定义三个类,验证类体会在代码运行是进入运行,这一点与函数不同
class MyClass1():
print('11111')
class MyClass2():
print('22222')
class MyClass3():
print('33333')
"""
注意:
a.同一个py文件中可以定义多个类,但是,在实际项目开发中,如果需求较为复杂,类的定义建议一个py文件定义一个类
b.当一个函数定义完毕,则需要手动调用,否则无法执行,当一个类定义完毕,当类被加载的时候,其中的类体也会被加载
"""
# 二、创建对象/类的实例化
# 语法:对象名 = 类名(....),目前为空
mc1 = MyClass1()
print(mc1) # <__main__.MyClass1 object at 0x10726bdc0>
print(type(mc1)) # <class '__main__.MyClass1'> 【__main__.这个说明是我们自己创建的类】
mc2 = MyClass1()
print(mc2) #<__main__.MyClass1 object at 0x000001D4118B5FA0>
print(type(mc2)) #<class '__main__.MyClass1'>
num = 10
print(num) # 10
"""
注意:
a.创建对象的过程,本质上就是定义变量的过程,该变量中存储的是创建出来的对象的地址
b.打印对象的时候,默认的情况下,打印的是该对象在内存空间中的地址,
但是,像int,str,list。。。常用的数据类型,系统已经处理过了,所以直接打印结果
c.一个普通的类,可以创建无数个对象,每个对象在内存空间中拥有独立的地址
d.对象名 = 类名(....)表示创建对象,但是该代码执行一次,则表示创建一个新的对象
"""
#验证:a.创建对象的过程,本质上就是定义变量的过程,该变量中存储的是创建出来的对象的地址
s = MyClass1()
print(s) #<__main__.MyClass1 object at 0x000001D4118B5F70>
#验证:b.打印对象的时候,默认的情况下,打印的是该对象在内存空间中的地址,但是,像int,str,list。。。常用的数据类型,系统已经处理过了,所以直接打印结果
n = 5
print(n) #5
m = MyClass1()
print(m) #<__main__.MyClass1 object at 0x000001D4118B5A60>
#=================================================================
# 一、类中成员函数的定义
# 1.类的定义
class Person():
# 2.多个对象共同的特征:变量
# 3.多个对象共同的行为:函数
"""
说明:
a.self:自身,自己,在面向对象的函数中,self表示当前对象
b.哪个对象调用函数,则该函数中的self表示就是哪个对象
c.当调用函数的时候,self不需要手动传参,系统会自动完成传参,传递的是当前对象,只需要关注自定义的参数即可
d.在Python中,self并不是一个关键字,只要是个合法的标识符即可充当self的角色,但是,为了表示当前对象,一般使用self
e.一般pycharm会在定义类当中实例函数(对象函数)时,自动添加self
"""
# 实例函数/对象函数,特点:第一个形参必须是self,只能由对象调用
def run(self):
print("running",id(self))
def eat(self,sth):
print("eating" + sth)
# 二、类中成员函数的访问
# 注意1:类和函数相似,会引入新的作用域,所以在类中定义的函数在类的外面无法直接调用
# 注意2:行为主要是由对象执行的,所以类中的函数需要调用,可以通过对象调用,语法:对象.函数(实参)
p1 = Person()
print("p1~~~~~~",id(p1)) #p1~~~~~~ 2326877211952 【注意,这里打印的是p1对象的地址】
p1.run() #running 2326877211952 【注意,这里打印的是实例函数run当中的self的地址,验证self其实就是p1对象】
p1.eat('apple') #eatingapple
p2 = Person()
print("p2~~~~~~",id(p2)) #p2~~~~~~ 2326877211856
p2.run() #running 2326877211856
p2.eat("food") #eatingfood
#=================================================================
# 类中多个对象共同的特征:变量,也被称为属性
# 通过动态绑定的属性被称为对象属性或实例属性
# 1.对象属性的动态绑定
# 语法:对象.属性 = 值
class Person():
def show(self):
print(f"姓名:{self.name},年龄:{self.age},身高:{self.height}")
# 创建对象
p1 = Person()
# 动态绑定属性
p1.name = '张三'
p1.age = 18
p1.height = 170
print(p1.name,p1.age,p1.height) #张三 18 170
# 调用实例函数
p1.show() #姓名:张三,年龄:18,身高:170
p2 = Person()
# 注意1:给一个对象动态绑定的属性,另一个对象未绑定的情况下无法访问【动态绑定原则:谁用谁绑】
# print(p2.name) # AttributeError: 'Person' object has no attribute 'name'
p2.name = '李四'
p2.age = 10
p2.height = 180
p2.hobby = 'dance'
p2.show() #姓名:李四,年龄:10,身高:180
# 注意2:不同的对象绑定了同名的属性,当一个对象的属性值发生改变时,对另一个对象的属性没有影响
print(p1.name,p2.name) #张三 李四
p1.name = 'jack.张'
print(p1.name,p2.name) #jack.张 李四
# 2.限制绑定对象的属性
class People():
# 给系统属性__slots__定义一个元组,元组的元素就是允许绑定的属性字段名称
# 注意1:为了限制当前类创建的对象只能绑定指定的属性
# 注意2:如果只需要限制一个属性,则书写元素的时候,注意添加逗号,如: __slots__ = ("name",)
__slots__ = ("name", 'age', 'height') #slots /slɒts/ n. 插槽;老虎机(slot 的复数)
def show(self):
print(f"姓名:{self.name},年龄:{self.age},身高:{self.height}")
p2 = People()
p2.name = '李四'
p2.age = 10
p2.height = 180
# p2.hobby = 'dance' # AttributeError: 'People' object has no attribute 'hobby'
p2.show() #姓名:李四,年龄:10,身高:180
三、类和对象的练习:
- 需求:开学了,王老师让学生小明,小丽,小花做自我介绍,
需要介绍自己的姓名,年龄,爱好,来一段才艺展示 - 说明
'''
练习:
需求:开学了,王老师让学生小明,小丽,小花做自我介绍,
需要介绍自己的姓名,年龄,爱好,来一段才艺展示
'''
class Teacher():
__slots__ = ("name",)
#ob是传进去的对象
def make_introduce(self,ob):
print(f'{self.name}老师说:接下来让{ob.name}同学做自我介绍')
if ob.name == '王星':
for i in range(0,3):
print(f'{self.name}老师强调说:{ob.name}同学是以全市第一的成绩考到咱们班的!')
elif ob.name == '王云':
for i in range(0,2):
print(f'{self.name}老师强调说:{ob.name}同学是以全市第二的成绩考到咱们班的!')
else:
print(f'{self.name}老师强调说:希望{ob.name}同学今后要要好好努力啊!')
ob.introduce()
ob.show()
class Student():
__slots__ = ('name','age','hobby')
def introduce(self):
print(f'{self.name}说:大家好,我叫{self.name},今年{self.age}岁了')
def show(self):
print(f'{self.name}说:我的爱好是{self.hobby}')
if __name__ == '__main__':
# 老师对象
wang = Teacher()
wang.name = 'wang' #如果没有这句代码会出现的报错:AttributeError: name
# 学生对象
wang_xing = Student()
wang_xing.name = '王星'
wang_xing.age = 18
wang_xing.hobby = '考第一'
wang_yun = Student()
wang_yun.name = '王云'
wang_yun.age = 15
wang_yun.hobby = '紧跟在第一个后面'
wang_hua = Student()
wang_hua.name = '王华'
wang_hua.age = 16
wang_hua.hobby = '摸鱼'
#调用wang的对象函数
l = [wang_xing,wang_yun,wang_hua]
for j in l:
wang.make_introduce(j)
print('=' * 20)
'''
容易出错的地方,有时候“类”相同的“对象”我们就会直接复制前一个对象来定义,这就有可能出现
忘记改掉前一个对象名字的问题,就会报错:AttributeError: name
'''
打印结果:
wang老师说:接下来让王星同学做自我介绍
wang老师强调说:王星同学是以全市第一的成绩考到咱们班的!
wang老师强调说:王星同学是以全市第一的成绩考到咱们班的!
wang老师强调说:王星同学是以全市第一的成绩考到咱们班的!
王星说:大家好,我叫王星,今年18岁了
王星说:我的爱好是考第一
====================
wang老师说:接下来让王云同学做自我介绍
wang老师强调说:王云同学是以全市第二的成绩考到咱们班的!
wang老师强调说:王云同学是以全市第二的成绩考到咱们班的!
王云说:大家好,我叫王云,今年15岁了
王云说:我的爱好是紧跟在第一个后面
====================
wang老师说:接下来让王华同学做自我介绍
wang老师强调说:希望王华同学今后要要好好努力啊!
王华说:大家好,我叫王华,今年16岁了
王华说:我的爱好是摸鱼
====================
Process finished with exit code 0