[Python学习日记-61] 什么是类与对象?类与对象是什么关系呢?我们该如何定义和使用类与对象呢?
[Python学习日记-61] 什么是类与对象?类与对象是什么关系呢?我们该如何定义和使用类与对象呢?
简介
类与对象
定义类与实例化出对象
如何使用类
如何使用对象
简介
前面我们了解了编程当中的不同流派有什么优缺点,同时也了解了什么是对象,本篇文章我们将引入另一个概念,那就是“类”。这个“类”与对象可以说是相辅相成,紧密结合,下面我们一起来了解一下吧。
类与对象
类就是一系列对象相似的特征与技能的结合体,而且站在不同的角度,得到的分类是不一样的,例如人、狗、笔、树是四个不同的对象,如果我们站在动物的角度来看人和狗是一类,如果我们站在生物的角度来看就是人、狗和树是一类,再如果我们站在物体的角度来看人、狗、笔、树又是一类。现实中的类并不完全等于程序中的类,例如现实中的公司类,在程序中有时需要拆分成部门类、业务类等。有时为了编程需求,程序中也可能会定义现实中不存在的类,例如策略类,在现实当中并不存在,但是在程序中却是一个很常见的类。
在上一篇文章当中我们提到每一个对象都有自己的信息和技能,如果多个对象有相似的数据与功能,那么该多个对象就属于同一种类。有了类的好处是:我们可以把同一类对象相同的信息和技能存放到类里,而无需每个对象都重复存一份,这样每个对象里只需存自己独有的数据即可,极大地节省了空间。所以,如果说对象是用来存放信息和技能的容器,那么类则是用来存放多个对象相同的信息和技能的容器。
定义类与实例化出对象
而在现实世界中,一定先有对象,后有类,但是在程序当中则是一定得先定义类,后调用类来产生对象, 结合上一篇文章介绍的对象来看,虽然我们是按照现实世界当中的先介绍对象后介绍类的,不过这也是想尽量讲得比较贴近现实世界来作为一个比较好接受的切入点,让各位更好的理解什么是类和对象。产生对象的类与对象之间存在关联,这种关联指的是:对象可以访问到类中共有的数据与功能,所以类中的内容仍然是属于对象的,类只不过是一种节省空间、减少代码冗余的机制,面向对象编程最终的核心仍然是去使用对象。
我们知道编程有两个流派,一个是面向过程编程,另一个是面向对象编程,而类就是面向对象编程。我们以开发一个腾讯公司的员工管理系统为例,来简单介绍基于面向对象的思想如何编写程序。在一家公司当中会有不同的角色,会有老板、高管、员工等,显而易见的是每个角色肯定都有不通的信息与技能,而面向对象的基本思路就是把程序中要用到的、相关联的信息与技能整合到对象里,然后再去使用,在这么多个角色当中我们应该如何找到相关连的呢?下面我们以员工为例
# 员工的信息有
公司
姓名
年龄
身高
# 员工的技能有
工作
吃饭
睡觉
再详细到每一个员工
# 员工1
信息:
公司=腾讯公司
姓名=王二丫
年龄=25
身高=175
技能:
工作
吃饭
睡觉
# 员工2
信息:
公司=腾讯公司
姓名=李三炮
年龄=28
身高=165
技能:
工作
吃饭
睡觉
# 员工3
信息:
公司=腾讯公司
姓名=张铁蛋
年龄=22
身高=190
技能:
工作
吃饭
睡觉
看着上面详细的信息与技能,我们归纳同类项,我们可以总结出一个员工类,用来存放员工们相同的信息与技能
# 员工类
相同的信息:
公司=腾讯公司
相同的技能:
工作
吃饭
睡觉
上面是基于现实世界的分析的出来的一个类,那么我们接下来看看如何在程序中定义出类
#先定义类
class TencentEmployees:
company='tencent'
def work(self):
print('is working')
def eat(self):
print('is eating')
def sleep(self):
print('is sleeping')
类体最常见的是变量的定义和函数的定义,但其实类体可以包含任意 Python 代码,类体的代码在类定义阶段就会执行,我们来试验一下
#先定义类
class TencentEmployees:
company='tencent'
def work(self):
print('is working')
def eat(self):
print('is eating')
def sleep(self):
print('is sleeping')
print("------class is run------")
代码输出如下:
下面来看看我们应该如何调用类,调用类的过程称为将类实例化,拿到的返回值就是程序中的对象,或称为一个实例
#后产生对象
emp1=TencentEmployees()
emp2=TencentEmployees()
emp3=TencentEmployees()
print(emp1)
print(emp2)
print(emp3)
代码输出如下:
如何使用类
类有两大核心概念,一个是对属性的操作,类的属性有两种分别是数据属性和函数属性,对应的就是我们前面说的信息和技能;另一个是实例化产生对象,而实例化产生对象已经在前面演示过如何创建,但是前面创建的实例都是创建一些共有的信息,并没有各自独有的信息,而这个需要使用到 __init__ 方法,这也会在本节中得到补充。
一、对类属性的操作
1、查看类的名称空间
当定义一个类是它会创建自己的命名空间,类产生新的名称空间是用来存放类中定义的名字,可以使用 TencentEmployees.__dict__ 来查看类这个容器内盛放的东西
print(TencentEmployees.__dict__)
代码输出如下:
{'__module__': '__main__', 'company': 'tencent', 'work': <function TencentEmployees.work at 0x000001619D618CC0>, 'eat': <function TencentEmployees.eat at 0x000001619D618B80>, 'sleep': <function TencentEmployees.sleep at 0x000001619D6199E0>, '__dict__': <attribute '__dict__' of 'TencentEmployees' objects>, '__weakref__': <attribute '__weakref__' of 'TencentEmployees' objects>, '__doc__': None}
与之前看到的命名空间一样,类的命名空间的表现形式也是一个字典,也可以使用字典的形式来调用类里面的名字
print(TencentEmployees.__dict__['company'])
print(TencentEmployees.__dict__['work'])
代码输出如下:
在类中定义的名字,都是类的属性,即数据属性和函数属性,可以通过 __dict__ 访问属性的值,就像上面的代码一样,但 Python 提供了专门的属性访问语法
print(TencentEmployees.company)
print(TencentEmployees.work)
代码输出如下:
操作对象的属性也是一样,这我们将在对象的使用当中演示。
2、查
类的查其实就跟上面查看名称空间是一致的,Python 有专门提供给访问类属性的语法,我们比较常用的查询类属性方法就是使用这种方法,如下
#先定义类
class TencentEmployees:
company='tencent'
def work(self):
print('is working')
def eat(self):
print('is eating')
def sleep(self):
print('is sleeping')
print(TencentEmployees.company) # TencentEmployees.__dict__['company']
print(TencentEmployees.work) # TencentEmployees.__dict__['work']
代码输出如下:
3、增
类的名称空间是一个字典,所以增加时也可以使用字典添加 key-value 的形式来增加,不过不太建议在增加类属性时是用字典的形式来增加,我们可以在访问类属性的基础上进行赋值操作,如下
TencentEmployees.county = 'China'
print(TencentEmployees.__dict__)
print(TencentEmployees.county)
代码输出如下:
{'__module__': '__main__', 'company': 'tencent', 'work': <function TencentEmployees.work at 0x000001CA3D798AE0>, 'eat': <function TencentEmployees.eat at 0x000001CA3D798B80>, 'sleep': <function TencentEmployees.sleep at 0x000001CA3D7999E0>, '__dict__': <attribute '__dict__' of 'TencentEmployees' objects>, '__weakref__': <attribute '__weakref__' of 'TencentEmployees' objects>, '__doc__': None, 'county': 'China'}
4、删
类属性的删除操作其实也跟字典的删除操作一样,不过和查和增一样,语法都是自成一系的,但是相同的是都需要用到 Python 提供的 del 来处理,如下
del TencentEmployees.county
print(TencentEmployees.__dict__)
代码输出如下:
# 删除前
{'__module__': '__main__', 'company': 'tencent', 'work': <function TencentEmployees.work at 0x0000018FED988CC0>, 'eat': <function TencentEmployees.eat at 0x0000018FED988B80>, 'sleep': <function TencentEmployees.sleep at 0x0000018FED9899E0>, '__dict__': <attribute '__dict__' of 'TencentEmployees' objects>, '__weakref__': <attribute '__weakref__' of 'TencentEmployees' objects>, '__doc__': None, 'county': 'China'}
# 删除后
{'__module__': '__main__', 'company': 'tencent', 'work': <function TencentEmployees.work at 0x0000018FED988CC0>, 'eat': <function TencentEmployees.eat at 0x0000018FED988B80>, 'sleep': <function TencentEmployees.sleep at 0x0000018FED9899E0>, '__dict__': <attribute '__dict__' of 'TencentEmployees' objects>, '__weakref__': <attribute '__weakref__' of 'TencentEmployees' objects>, '__doc__': None}
5、改
类属性的修改操作跟增加操作差不多,也是进行一个赋值操作,如下
TencentEmployees.company= 'Tencent'
print(TencentEmployees.company)
代码输出如下:
二、实例化产生对象(__init__方法的补充)
前面我们在介绍定义类与实例化出对象时就介绍了对象的实例化了,但是那时候的实例化的对象都只是拥有相同的属性,并没有各自独有的属性,也就是说上面的 emp1、emp2、emp3 全都是一样了的,想在实例化的过程中就为三位学生定制各自独有的数据:姓名、年龄、身高,需要我们在类内部新增一个__init__方法,如下
class TencentEmployees:
company='tencent'
#该方法会在对象产生之后自动执行,专门为对象进行初始化操作,可以有任意代码,但一定不能返回非None的值;注意,这里的Name、Age、Height开头大写为的是区分,并不是固定写法
def __init__(self,name,age,height):
self.Name = name
self.Age = age
self.Height = height
def work(self):
print('is working')
def eat(self):
print('is eating')
def sleep(self):
print('is sleeping')
在加入 __init__ 方法后实例化对象时需要输入对应的参数
emp1=TencentEmployees("王二丫",25,175)
emp2=TencentEmployees("李三炮",28,165)
emp3=TencentEmployees("张铁蛋",22,190)
print(emp1)
print(emp2)
print(emp3)
代码输出如下:
这里有的小伙伴会有点疑问,__init__ 方法和其他方法里面的 self 是什么意思呢?其实这个 self 的意思是表示对象本身,在调用对象自己命名空间内的数据时非常有用。但是为什么我们进行实例化对象的时候又不需要加入这个对象本身呢?我们单拿 emp1 的产生过程来分析,调用类会先产生一个空对象 emp1,然后将 emp1 连同调用类时括号内的参数一起传给 TencentEmployees.__init__(emp1,"王二丫",25,175),如下
def __init__(self,name,age,height):
self.Name = name # emp1.Name = "王二丫"
self.Age = age # emp1.Age = 25
self.Height = height # emp1.Height = 175
实例化对象时会产生对象的名称空间,同样可以用 __dict__ 查看
print(emp1.__dict__)
代码输出如下:
{'Name': '王二丫', 'Age': 25, 'Height': 175}
这样我们就创造了三个存有共有属性和独有属性的三个对象了,其中共有属性都存放在同一个类当中,关系图如下
如何使用对象
一、查看对象的名称空间
前面我们介绍了类的名称空间,它是用于存储对象之间共有的属性,而对象各自独有的属性就是存储在各自的名称空间之中,我们把这个名称空间称之为对象名称空间,他会在实例化对象的时候进行创建。对象名称空间的查看方法与类名称空间的查看方法是一样的,如下
print(emp1.__dict__)
代码输出如下:
{'Name': '王二丫', 'Age': 25, 'Height': 175}
与类名称空间一样,对象的命名空间的表现形式也是一个字典,也可以和类名称空间一样进行字典的操作
print(emp1.__dict__['Name'])
print(emp1.__dict__['Age'])
代码输出如下:
在 Python 中也有专用的语法用于对象属性的访问,语法与类名称空间是差不多的,如下
print(emp1.Name)
print(emp1.Age)
代码输出如下:
二、查
对象的查询既可以查询对象独有的名称空间中的属性,也可以查询类中共有的名称空间中的属性,使用方法如下
# __init__方法用来为对象定制对象自己独有的特征
class TencentEmployees:
company='tencent'
def __init__(self,name,age,height):
self.Name = name
self.Age = age
self.Height = height
def work(self):
print('is working')
def eat(self):
print('is eating')
def sleep(self):
print('is sleeping')
# 后产生对象
emp1=TencentEmployees("王二丫",25,175) # TencentEmployees.__init__(emp1,"王二丫",25,175)
# 加上__init__方法后,实例化的步骤
# 1、先产生一个空对象emp1
# 2、TencentEmployees.__init__(emp1,"王二丫",25,175)
# 查
print(emp1.__dict__)
print(emp1.Name)
print(emp1.Age)
print(emp1.Height)
print(emp1.company)
emp1.work()
emp1.eat()
emp1.sleep()
代码输出如下:
三、增
emp1.deportment_name = 'python开发小组'
print(emp1.__dict__)
代码输出如下:
四、删
del emp1.Name
print(emp1.__dict__)
代码输出如下:
五、改
emp1.Name = '李二丫'
print(emp1.__dict__)
print(emp1.Name)
代码输出如下: