类是Object Oriented Programming 的支柱。 OOP 高度关注代码组织、可重用性和封装性。
首先,免责声明:OOP 与Functional Programming 部分相反,Functional Programming 是 Python 中经常使用的不同范式。并非所有使用 Python(或者肯定是大多数语言)编程的人都使用 OOP。你可以在 Java 8 中做很多不是非常面向对象的事情。如果您不想使用 OOP,请不要使用。如果您只是编写一次性脚本来处理您永远不会再次使用的数据,那么请继续按照您的方式编写。
但是,使用 OOP 的原因有很多。
一些原因:
-
组织:
OOP 定义了在代码中描述和定义数据和过程的众所周知的标准方法。数据和过程都可以存储在不同的定义级别(在不同的类中),并且有谈论这些定义的标准方法。也就是说,如果你以一种标准的方式使用 OOP,它将帮助你以后的自己和其他人理解、编辑和使用你的代码。此外,您可以命名数据结构片段并方便地引用它们,而不是使用复杂的任意数据存储机制(dicts 或列表或 dicts 或集合的 dicts 列表等)。
李>
状态:OOP 帮助您定义和跟踪状态。例如,在一个经典示例中,如果您正在创建一个处理学生的程序(例如,一个年级程序),您可以将您需要的关于他们的所有信息保存在一个位置(姓名、年龄、性别、年级、课程、成绩、教师、同伴、饮食、特殊需求等),并且只要对象还活着,这些数据就会一直存在,并且易于访问。
Encapsulation:
通过封装,过程和数据存储在一起。方法(函数的 OOP 术语)与它们操作和产生的数据一起定义。在像 Java 这样允许access control 的语言中,或者在 Python 中,这取决于您如何描述公共 API,这意味着方法和数据可以对用户隐藏。这意味着如果您需要或想要更改代码,您可以对代码的实现做任何您想做的事情,但保持公共 API 不变。
Inheritance:
继承允许您在一个地方(在一个类中)定义数据和过程,然后在以后覆盖或扩展该功能。例如,在 Python 中,我经常看到人们创建 dict 类的子类以添加额外的功能。一个常见的更改是重写在从不存在的字典中请求键以基于未知键提供默认值时引发异常的方法。这允许您现在或以后扩展自己的代码,允许其他人扩展您的代码,并允许您扩展其他人的代码。
可重用性:所有这些原因和其他原因都可以提高代码的可重用性。面向对象的代码允许您编写可靠的(经过测试的)代码一次,然后一遍又一遍地重用。如果您需要针对特定用例进行一些调整,您可以从现有类继承并覆盖现有行为。如果您需要更改某些内容,您可以在保持现有公共方法签名的同时进行全部更改,没有人比这更聪明(希望如此)。
同样,不使用 OOP 有几个原因,您也不需要这样做。但幸运的是,对于 Python 这样的语言,你可以使用一点点或很多,这取决于你。
学生用例的一个例子(不保证代码质量,只是一个例子):
面向对象
class Student(object):
def __init__(self, name, age, gender, level, grades=None):
self.name = name
self.age = age
self.gender = gender
self.level = level
self.grades = grades or {}
def setGrade(self, course, grade):
self.grades[course] = grade
def getGrade(self, course):
return self.grades[course]
def getGPA(self):
return sum(self.grades.values())/len(self.grades)
# Define some students
john = Student("John", 12, "male", 6, {"math":3.3})
jane = Student("Jane", 12, "female", 6, {"math":3.5})
# Now we can get to the grades easily
print(john.getGPA())
print(jane.getGPA())
标准字典
def calculateGPA(gradeDict):
return sum(gradeDict.values())/len(gradeDict)
students = {}
# We can set the keys to variables so we might minimize typos
name, age, gender, level, grades = "name", "age", "gender", "level", "grades"
john, jane = "john", "jane"
math = "math"
students[john] = {}
students[john][age] = 12
students[john][gender] = "male"
students[john][level] = 6
students[john][grades] = {math:3.3}
students[jane] = {}
students[jane][age] = 12
students[jane][gender] = "female"
students[jane][level] = 6
students[jane][grades] = {math:3.5}
# At this point, we need to remember who the students are and where the grades are stored. Not a huge deal, but avoided by OOP.
print(calculateGPA(students[john][grades]))
print(calculateGPA(students[jane][grades]))