Файл: Объектноориентированное программирование на Python.docx
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 10.04.2024
Просмотров: 34
Скачиваний: 0
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
В случае классов используется особая терминология. Пусть имена, определенные в классе, называются атрибутами этого класса. В примере имена n и adder – это атрибуты класса B. Атрибуты-переменные часто называют полями или свойствами (в других языках понятия "поле" и "свойство" не совсем одно и то же). Полем является n. Атрибуты-функции называются методами. Методом в классе B является adder. Количество свойств и методов в классе может быть любым.
Переменные класса и объекта
Данные, т.е. поля, являются не чем иным, как обычными переменными, заключёнными в пространствах имён классов и объектов. Это означает, что их имена действительны только в контексте этих классов или объектов. Отсюда и название “пространство имён”.
Существует два типа полей: переменные класса (рассмотрели выше) и переменные объекта, которые различаются в зависимости от того, принадлежит ли переменная классу или объекту соответственно.
Переменные класса разделяемы – доступ к ним могут получать все экземпляры этого класса. Переменная класса существует только одна, поэтому когда любой из объектов изменяет переменную класса, это изменение отразится и во всех остальных экземплярах того же класса.
Переменные объекта принадлежат каждому отдельному экземпляру класса. В этом случае у каждого объекта есть своя собственная копия поля, т.е. не разделяемая и никоим образом не связанная с другими такими же полями в других экземплярах. Это легко понять на примере (сохраните как objvar.py):
class Robot: '''Представляет робота с именем.''' # Переменная класса, содержащая количество роботов population = 0 def __init__(self, name): '''Инициализация данных.''' self.name = name print('(Инициализация {0})'.format(self.name)) # При создании этой личности, робот добавляется # к переменной 'population' Robot.population += 1 def __del__(self): '''Я умираю.''' print('{0} уничтожается!'.format(self.name)) Robot.population -= 1 if Robot.population == 0: print('{0} был последним.'.format(self.name)) else: print('Осталось {0:d} работающих роботов.'.format(Robot.population)) def sayHi(self): '''Приветствие робота. Да, они это могут.''' print('Приветствую! Мои хозяева называют меня {0}.'.format(self.name)) def howMany(): '''Выводит численность роботов.''' print('У нас {0:d} роботов.'.format(Robot.population)) howMany = staticmethod(howMany) droid1 = Robot('R2-D2') droid1.sayHi() Robot.howMany() droid2 = Robot('C-3PO') droid2.sayHi() Robot.howMany() print("\nЗдесь роботы могут проделать какую-то работу.\n") print("Роботы закончили свою работу. Давайте уничтожим их.") del droid1 del droid2 Robot.howMany() |
Вывод:
$ python3 objvar.py
(Инициализация R2-D2)
Приветствую! Мои хозяева называют меня R2-D2.
У нас 1 роботов.
(Инициализация C-3PO)
Приветствую! Мои хозяева называют меня C-3PO.
У нас 2 роботов.
Здесь роботы могут проделать какую-то работу.
Роботы закончили свою работу. Давайте уничтожим их.
R2-D2 уничтожается!
Осталось 1 работающих роботов.
C-3PO уничтожается!
C-3PO был последним.
У нас 0 роботов.
Как это работает:
Это длинный пример, но он помогает продемонстрировать природу переменных класса и объекта. Здесь population принадлежит классу Robot, и поэтому является переменной класса. Переменная name принадлежит объекту (ей присваивается значение при помощи self), и поэтому является переменной объекта.
Таким образом, мы обращаемся к переменной класса population как Robot.population, а не self.population. К переменной же объекта name во всех методах этого объекта мы обращаемся при помощи обозначения self.name. Помните об этой простой разнице между переменными класса и объекта. Также имейте в виду, что переменная объекта с тем же именем, что и переменная класса, сделает недоступной (“спрячет”) переменную класса!
Метод howMany принадлежит классу, а не объекту.
Примечание:
В этом примере мы также наблюдали применение строк документации для классов, равно как и для методов. Во время выполнения мы можем обращаться к строке документации класса при помощи Robot.__doc__, а к строке документации метода – при помощи Robot.sayHi.__doc__.
Динамическое изменение (не рекомендуется использовать)
Классы в Python могут динамически изменяться после определения:
class SomeClass(object): # пустой класс pass a = SomeClass() b = SomeClass() a.arg = 1 # у экземпляра a появился атрибут arg, равный 1 b.arg = 2 # а у экземпляра b - атрибут arg, равный 2 print(a.arg) print(b.arg) c = A() print(c.arg) # а у этого экземпляра нет arg |
* python позволяет добавлять новые атрибуты в любой экземпляр класса в любом месте программы, но так делать не рекомендуется, т.к. это может привести к неправильной работе экземпляра.
Примечание:
При вызове метода экземпляра класса, ссылка на экземпляр передается первым аргументом. При этом, экземпляр передается неявно, но параметр надо указывать явно.
Практическая работа “Игра воин”:
Напишите программу по следующему описанию. Есть класс "Воин". От него создаются два экземпляра-юнита. Каждому устанавливается здоровье в 100 очков. В случайном порядке они бьют друг друга. Тот, кто бьет, здоровья не теряет. У того, кого бьют, оно уменьшается на 20 очков от одного удара. После каждого удара надо выводить сообщение, какой юнит атаковал, и сколько у противника осталось здоровья. Как только у кого-то заканчивается ресурс здоровья, программа завершается сообщением о том, кто одержал победу.