Классы являются опорой объектно-ориентированного программирования . ООП очень заботится об организации кода, возможности его повторного использования и инкапсуляции.
Во-первых, отказ от ответственности: ООП частично контрастирует с функциональным программированием , которое является другой парадигмой, часто используемой в Python. Не каждый, кто программирует на Python (или, конечно, большинство языков), использует ООП. В Java 8 вы можете многое сделать, если вы не очень объектно-ориентированы. Если вы не хотите использовать ООП, то не делайте этого. Если вы просто пишете одноразовые сценарии для обработки данных, которые вы никогда не будете использовать снова, продолжайте писать так, как есть.
Однако есть много причин использовать ООП.
Несколько причин:
Организация: ООП определяет хорошо известные и стандартные способы описания и определения как данных, так и процедур в коде. Как данные, так и процедуры могут храниться на разных уровнях определения (в разных классах), и существуют стандартные способы говорить об этих определениях. То есть, если вы используете ООП стандартным способом, это поможет вашему самому себе и другим понять, отредактировать и использовать ваш код. Кроме того, вместо использования сложного, произвольного механизма хранения данных (диктов диктов или списков, диктов или списков диктов множеств или чего-либо еще), вы можете называть фрагменты структур данных и удобно ссылаться на них.
Состояние: ООП помогает вам определять и отслеживать состояние. Например, в классическом примере, если вы создаете программу, которая обрабатывает учащихся (например, программу оценки), вы можете хранить всю необходимую вам информацию о них в одном месте (имя, возраст, пол, уровень образования, курсы, оценки, учителя, сверстники, диета, особые потребности и т. д.), и эти данные сохраняются, пока объект жив, и легко доступны.
Инкапсуляция . С помощью инкапсуляции процедура и данные хранятся вместе. Методы (термин ООП для функций) определяются прямо рядом с данными, с которыми они работают и производят. В таком языке, как Java, который допускает управление доступом , или в Python, в зависимости от того, как вы описываете свой публичный API, это означает, что методы и данные могут быть скрыты от пользователя. Это означает, что если вам нужно или вы хотите изменить код, вы можете делать все, что захотите, для реализации кода, но оставляйте общедоступные API-интерфейсы такими же.
Наследование : Наследование позволяет вам определять данные и процедуры в одном месте (в одном классе), а затем переопределять или расширять эту функциональность позже. Например, в Python я часто вижу людей, создающих подклассы dict
класса, чтобы добавить дополнительную функциональность. Общее изменение переопределяет метод, который выдает исключение, когда ключ запрашивается из словаря, который не существует, чтобы дать значение по умолчанию на основе неизвестного ключа. Это позволяет вам расширять свой собственный код сейчас или позже, позволяет другим расширять ваш код и позволяет расширять код других людей.
Возможность многократного использования. Все эти и другие причины обеспечивают большую возможность повторного использования кода. Объектно-ориентированный код позволяет вам написать сплошной (проверенный) код один раз, а затем использовать снова и снова. Если вам нужно что-то настроить для конкретного случая использования, вы можете наследовать от существующего класса и перезаписать существующее поведение. Если вам нужно что-то изменить, вы можете изменить все это, поддерживая существующие сигнатуры открытых методов, и никто не станет мудрее (надеюсь).
Опять же, есть несколько причин не использовать ООП, и вам это не нужно. Но, к счастью, с таким языком, как 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())
Стандартный Dict
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]))