this статья завершает цикл материалов об объектно-ориентированном программировании. Если вы ещё не ознакомились с введением в ООП, следует это сделать.
Как известно, объекты имеют свойства. У каждого свойства есть имя, чтобы к нему обращаться.
Например, объект monster имеет свойство hp. Чтобы обратиться к нему, мы пишем:
monster.hp = 100;
Как видим, обращение всегда делается через объект, ведь свойство находится внутри объекта. Не написав сначала monster, мы не можем достучаться до hp.
Но кроме того, у объекта могут быть методы.
Методы могут работать с собственными свойствами объекта. Например, если мы хотим, чтобы объект-монстр каждый ход саморегенерировался (повышая hp на 10), мы можем написать для него метод regenerate(). Сделаем это через класс Monster:
Как можно видеть, метод класса Monster обращается к свойству собственного класса, чтобы изменить его. То есть доступ происходит не снаружи, а изнутри. Должны ли мы в данном случае получать доступ к этому свойству через имя объекта, как было описано выше?
С одной стороны, не должны, и в некоторых языках так и есть. Если мы написали hp, и в классе объявлено свойство hp, то транслятор понимает, что речь идёт именно о свойстве класса hp.
С другой стороны, некоторые языки такого не допускают. Они требуют явно указать, от какого объекта берётся свойство. Иначе это будет считаться не свойством, а обычной переменной. Но метод написан в классе, а класс – это лишь "чертеж" объекта. То есть там, где мы обращаемся к свойству hp, мы не можем указать никакой объект, потому что его попросту нет, он ещё не создан.
И что же тогда делать?
this.
Слово this указывает на объект изнутри. То есть объект снаружи может именоваться monster, player, fireball и т.д., и доступ к его свойствам будет работать через его имя. А внутри себя любой из этих объектов называется this. И доступ к его свойствам изнутри будет делаться через this. Стало быть, в методе класса, если того требует язык, можно написать так:
Несмотря на то, что при описании класса объект ещё не создан, слово this позволяет обозначить любой объект, который будет создан в будущем, и когда метод regenerate будет вызван, то this будет соответствовать созданному объекту.
Именно поэтому в статических методах нельзя использовать this – они вызываются без создания объекта и соответственно this там быть не может.
Языки Python и PERL идут немного другим путем. У них нет предопределенной ссылки на объект в виде this, но эта ссылка передаётся в метод как параметр, то есть в моих псевдоязычных примерах это выглядело бы так:
Но кто будет передавать эту ссылку? Должны ли мы писать вот так:
monster.regenerate(monster);
чтобы передать объект сам в себя? Нет, не должны. Ссылка self передается в метод автоматически и незаметно, не нарушая порядок тех параметров, которые мы передаем.
Также, отметьте, что self не является ключевым словом языка, таким как this. Это просто имя параметра, а имя может быть какое угодно. В Питоне оно называется self просто из-за общего соглашения.
На этом я заканчиваю цикл материалов про ООП. Вам осталось только учиться применять всё на практике, и стараться понять, как всё работает (этому способствует самостоятельная разработка чего-нибудь с нуля, а не переписывание готовых примеров).