Итак, программа, написанная с использованием парадигмы объектно-ориентированного программирования, должна состоять из
Объект в программе можно создать лишь на основе какого-нибудь класса. Поэтому, первым делом, ООП должно начинаться с проектирования и создания классов. Классы могут располагаться или вначале кода программы, или импортироваться из других файлов-модулей (также в начале кода).
Для создания классов предусмотрена инструкция class. Это составная инструкция, которая состоит из строки заголовка и тела. Заголовок состоит из ключевого слова class, имени класса и, возможно, названий суперклассов в скобках. Суперклассов может и не быть, в таком случае скобки не требуются. Тело класса состоит из блока различных инструкций. Тело должно иметь отступ (как и любые вложенные конструкции в языке Python).
Схематично класс можно представить следующим образом:
class ИМЯКЛАССА: ПЕРЕМЕННАЯ = ЗНАЧЕНИЕ …. def ИМЯМЕТОДА(self, ...): self.ПЕРЕМЕННАЯ = ЗНАЧЕНИЕ … ….
Следует помнить, что методы в классах — это те же функции, за одним небольшим исключением. Они принимают один обязательный параметр — self (с англ. можно перевести как "собственная личность"). Он нужен для связи с конкретным объектом.
Атрибуты класса — это имена переменных вне функций и имена функций. Эти атрибуты наследуются всеми объектами, созданными на основе данного класса. Атрибуты обеспечивают свойства и поведение объекта. Объекты могут иметь атрибуты, которые создаются в теле метода, если данный метод будет вызван для конкретного объекта.
Объекты создаются так:
ПЕРЕМЕННАЯ = ИМЯКЛАССА()
Здесь скобки обязательны! После такой инструкции в программе появляется объект, доступ к которому можно получить по имени переменной, связанной с ним. При создании объект получает атрибуты его класса, т. е. объекты обладают характеристиками, определенными в их классах.
Количество объектов, которые можно создать на основе того или иного класса, не ограничено.
Объекты одного класса имеют схожий набор атрибутов, а вот значения атрибутов могут быть разными. Другими словами, объекты одного класса похожи, но индивидуально различимы. Чтобы понять это, можно сравнить отношения объектов одного класса в программировании со следующем высказыванием: "Все млекопитающие принадлежат одному классу и обычно имеют по два глаза, однако у каждого животного (объекта) глаза имеют свои особенности".
Можно сказать, что методы класса — это небольшие программки, предназначенные для работы с объектами. Методы могут создавать новые свойства (данные) объекта, изменять существующие, выполнять другие действия над объектами.
Методу необходимо "знать", данные какого объекта ему предстоит обрабатывать. Для этого ему в качестве первого (а иногда и единственного) аргумента передается имя переменной, связанной с объектом (можно сказать, передается сам объект). Чтобы в описании класса указать передаваемый в дальнейшем объект, используется параметр self. (Посмотрите на схему класса вверху.)
С другой стороны, вызов метода для конкретного объекта в основном блоке программы выглядит следующим образом:
ОБЪЕКТ.ИМЯМЕТОДА(…)
Здесь под словом ОБЪЕКТ имеется ввиду переменная, связанная с ним. Это выражение преобразуется в классе, к которому относится объект, в
ИМЯМЕТОДА(ОБЪЕКТ, …)
Т. е. конкретный объект подставляется вместо параметра self.
Попробуем на основе имеющихся уже знаний написать небольшую ОО-программу. Допустим, это будет класс с одним атрибутом вне метода и одним методом, который выводит с небольшим изменением значение этого атрибута на экран:
class First: color = "red" def out(self): print (self.color + "!")
Теперь создадим пару объектов данного класса:
obj1 = First() obj2 = First()
Оба этих объекта (obj1 и obj2) имею два одинаковых атрибута: color (в виде свойства) и printer (в виде метода). Это легко проверить:
print (obj1.color) print (obj2.color) obj1.out() obj2.out()
В результате выполнения данного скрипта получается вывод двух надписей red и двух red!. Первые две надписи red – это результат применения встроенной функции print по отношению к свойствам объектов. Вторые две надписи red! - результат применения метода out к объектам.
В предыдущей программе оба созданных объекта абсолютно одинаковы. Класс, на основе которого они созданы слишком прост и не предполагает того, что объекты могут иметь различные значения свойств. Исправим это.
Пусть теперь в классе с помощью атрибутов вне функции устанавливаются два свойства объектов: красный цвет и круглая форма. А методы могут менять эти свойства в зависимости от пожеланий тех, кто создает объекты.
class Second: color = "red" form = "circle" def changecolor(self,newcolor): self.color = newcolor def changeform(self,newform): self.form = newform obj1 = Second() obj2 = Second() print (obj1.color, obj1.form) # вывод на экран "red circle" print (obj2.color, obj2.form) # вывод на экран "red circle" obj1.changecolor("green") # изменение цвета первого объекта obj2.changecolor("blue") # изменение цвет второго объекта obj2.changeform("oval") # изменение формы второго объекта print (obj1.color, obj1.form) # вывод на экран "green circle" print (obj2.color, obj2.form) # вывод на экран "blue oval"
В данной программе по-умолчанию любой созданный объект имеет красный цвет и круглую форму. Однако в дальнейшем с помощью методов данного класса можно поменять и цвет и форму любого объекта. В результате объекты перестают быть одинаковыми (красными и круглыми), хотя сохраняют тот же набор свойств (цвет и форму).
Как же происходят изменения? Дело в том, что методы помимо параметра self, могут иметь и другие параметры, в которых передаются данные для обработки их этим методом. Так, в примере выше, метод changecolor имеет дополнительный параметр newcolor, с помощью которого, в метод можно передать данные о желаемом цвете фигуры. Далее метод меняет цвет с помощью соответствующих инструкций.