面向对象编程思想和类的解析
一、面向对象思想:对象
面向对象的思想着重体现在“对象这两个字”。我们应该怎么理解对象呢?
对象:一个用来存放数据与功能的“容器”。
面向过程编程的思想是最基础的思想,如果我们用面向过程的思想去编写一个大项目,那么随着代码量的增加,会导致内部的代码越来越多,当我们这个时候想去找某个功能的时候,就会发现很难找,这个时候,这就是耦合度太高。而面向对象则可以将代码变得相对清晰一些。
如果我们进图书馆,就会发现内部的图书一般都将书都按分类进行存放,我们想要看文学类的可以去文学类的取余进行寻找,而这个文学区就可以称之为“对象”。因为所有与文学有关的书都存放在这个地方让我们方便查找,就像之前学的模块一样,他也是利用了“对象”的思想,将某些功能相关的代码放到一个模块中,再比如说字典、列表、原则等等,都是“容器”类型,其内部都可以用来存放数据和功能。
这就是面向对象的编程思想。
二、类
假设我们要做一个学生选课程的系统,首先我们将与学生有关的功能都放到了一起,将课程有关的功能都放到一起。
stu_name = "tom"
stu_age = 18
stu_gender = "man"
def tell_stu_info():
print(f"姓名:{stu_name} 年龄:{stu_age} 性别:{stu_gender}")
def change_info(x,y,z):
stu_name = x
stu_age = y
stu_gender = z
但这只是一个人的,我们可以改造成字典的方式存放每一个人的信息与功能,这样每一个字典就可以代表一个学生对象。
stu_1 = {
"stu_name" : "tom",
"stu_age" : 18,
"stu_gender" : "man",
"tell_info":tell_stu_info,
"change_info":change_info
}
这样的话,每个人的信息都存放到了一个字典里,我们可以有stu1,stu2,stu3....但是每个人的信息都有很多信息是重复的,比较占内存,Python提供了一个简单的方法,这就是类。
类:将对象中所有相似的数据与功能的集合体放在一起。
所以一般情况下,类内部都是变量与函数的定义,当然,你也可以在内部写其他代码,但是要注意一点:类内部代码在定义的时候就会执行,产生类的名称空间。
# 类名一般都是采用驼峰体:单词首字母大写。
class Student:
school = "Old boy"
def tell_info(stu_obj):
print("姓名:%s 年龄:%s 性别:%s"% (stu_obj["name"],stu_obj["age"],stu_obj["sex"]))
def set_info(stu_obj, x,y,z):
stu_obj.__dict__["stu_name"]= x
stu_obj.__dict__["stu_age"] = y
stu_obj.__dict__["stu_gender"] = z
此时,Student.__dict__字典内部就会显示变量名、函数名与内存地址一一对应的k=v的键值对。
# 向类内部查看属性的方式,这两者效果是一样的。
Student.__dict__["school"]
那么此时我们在做出学生1的信息就可以这么做。当调用类生成对象的模板的时候,其__dict__就会为空。
stu1 = Student()
stu1.stu_name = "tom"
stu1.stu_age = 18
stu1.stu_gender = "man"
如果有很多学生我们可以定义一个函数,然后实例化一个个学生对象,但还有简单的用法,当我们在使用类创造出来一个模板的时候,就自动启动一个函数,将参数传入,直接生成一个对象。
# 在内部使用__init__的函数就可以在创造学生对象的时候,传入参数自动生成学生1的信息。
class Student:
school = "Old boy"
def __init__(obj,x,y,z):
obj.name = x
obj.age = y
obj.sex = z
def tell_info(stu_obj):
print("姓名:%s 年龄:%s 性别:%s"%(stu_obj["name"],stu_obj["age"],stu_obj["sex"]))
def set_info(stu_obj, x,y,z):
stu_obj.name= x
stu_obj.age = y
stu_obj.sex = z
类的属性无法利用__dict__进行增删改操作,会报错,但是可以使用类.属性进行。而对象的属性则是可以进行增删改查的操作。
调用类的过程会发生3件事:
- 先产生一个空对象。
- python自动调用__init__函数。
- 返回初始完的对象。
__init__方法总结:
- 调用 类之后自动执行。
- 内部主要存放对象的私有属性,属于私人订制。本质仍是函数。
- 必须返回None。
三、绑定方法
类内部的属性都是为对象所用,其中,数据属性是所有对象共同使用类内定义的内存地址,如果对象本身有该属性,那么会使用本身的,查找顺序为对象本身-->类。
如果想改对象本身的数据属性,可以直接修改自身,如果想要修改全部对象的某一属性,那么就直接去修改类内部的数据属性。
类内的函数属性又有所不同,虽然其函数属性也是让所有对象拥有该函数属性,但是绑定不同的对象使用的绑定方法不同,其每个对象的函数的内存地址也有所不同。
# 原则上类函数属性的用法
Student.tell_info(stu1_obj)
Student.tell_info(stu2_obj)
Student.tell_info(stu3_obj)
# 由于绑定方法不同,用法也就不一样。
stu1.tell_info()
stu2.tell_info()
stu3.tell_info()
绑定方法的特殊之处是哪个对象来调用绑定的方法,那么这个对象就会被当作第一个参数传入。
因此,在类内部定义的函数属性的第一个参数一般都是对象本身,约定俗成地使用self。