- Регистрация
- 12 Янв 2024
- Сообщения
- 76
- Реакции
- 10
- Баллы
- 8
Класс
В ОО логике класс представляет собой описание того, как будет "выглядеть" вещь, если бы она была создана. Класс является общим шаблоном. Он определяет абстрактные свойства (например, деталь машины имеет свой цвет), но, обычно, не определяет реальное проявление этих свойств в природе (например, какого цвета деталь). Класс также определяет поведение объекта. Набор специальных функций однозначно указывает, как будет "вести" себя объект в Вашей программе. На языке программистов, такие абстрактные свойства называются "переменными экземпляра" (instance variables), а функции, описывающие поведение объекта - "методами" (method). Процесс создания объекта на основе класса называется "реализацией" (instantiation). Очень важно понимать, что класс не является объектом, а представляет собой шаблон, на основе которого эти объекты могут быть созданы. Когда Вы создаете объект (экземпляр класса), Вы создаете модель из шаблона.
Механика класса
В Unreal Script мы определяем классы посредством "объявления класса" (class declaration):
Ключевое слово class говорит Unreal Script, что Вы объявляете новый класс. MyClass, в данном случае, является именем нового класса (имя может быть любое, но желательно, со смыслом, например, CarPart). Оставшуюся часть мы рассмотрим несколько позже.
После того, как Вы объявили новый класс в Unreal Script, самое время определить переменные экземпляра. Все что Вам нужно для этого сделать - это указать список необходимых свойств:
Для более детального ознакомления с типами переменных в Unreal Script прочитайте туториал "UnrealScript Language Reference" (автор Tim Sweeney). Довольно изящно будет, если Вы отделите переменные от основной части кода комментариями:
Вообще, это дело вкуса, и общему делу не повредит. Обычно комментарии являются хорошим тоном в программировании. Они делают Ваш код более "читабельным" и понятным постороннему человеку, особенно если Вы собираетесь поделиться исходником с кем-то или вернуться к нему позже сами.
Определение методов в новом классе очень похоже на объявление переменных: просто составьте список необходимых функций:
И снова, Вы можете отделить методы от остального кода при помощи комментариев. Также, рекомендуется давать методам "внятные" имена, отражающие его суть. Например, метод, моющий Ваши носки 8) может быть назван cleanSocks()1.
В Unreal Script, создание объектов называется "spawning" (порождение). Вот как можно использовать функцию Spawn() для создания нового объекта из класса-шаблона:
Краткое обсуждение методов
Объект является независимым контейнером данных, которые "висят" в памяти. Ключевым словом является именно независимость. Каждый объект выполняет свою работу. Если Вы описали класс MyBot и создали два объекта (экземпляра) из этого класса с именами BotA и BotB эти два объекта ничего друг о друге не знают и даже не подозревают о существовании друг друга. Это приводит нас к следующей концепции объектно-ориентированного программирования: объекты изменяют сами себя.
Когда создается объект он вставляется в хэш таблицу в памяти и ему присваивается индивидуальный ключ поиска, затем о нем забывается. Система находит объект по ключу в случае, если Вы хотите что-то с ним сделать, для всех остальных целей объект является "как бы" недоступным. Недоступность проявляется в том, что Вы не можете просто взять и поменять объект как обычную переменную. Вы не можете, например, открыть объект и изменить содержащиеся в нем переменные (это одно из основных отличий объектов от структур в языке С++). Вместо этого, Вы говорите объекту изменить самого себя. Это производится посредством методов.
Методы класса определяют, каким образом будет действовать объект после создания. Если Вы хотите изменить переменную экземпляра (объекта), Вам необходимо описать соответствующий метод, который позволяет это сделать. Наш класс CarPart может иметь, например, такой метод:
В данном примере, когда вызывается метод setColor(), объект принимает число в качестве аргумента и устанавливает значение цвета равное этому числу. То есть объект изменяет сам себя. Синтаксис вызова метода в Unreal Script выглядит следующим образом:
Методы, переменные, и защита объектов
Помните, я Вам говорил, что объекты изменяют сами себя? На самом деле это не совсем так. Я так говорил, т.к. хотел, чтобы Вы думали об объектах, как о независимых "существах" в Вашей программе. Говоря на чистоту, переменные экземпляра можно менять напрямую:
Обратите внимание на отличие. В случае с методом, мы говорим объекту изменить себя, а в последнем - меняем природу объекта напрямую. Это иллюстрирует очередной момент "Как думают программисты". Вы, возможно, спрашиваете себя: "Если я могу изменять объект напрямую, то зачем мне вообще нужны эти методы, и какая от них польза?". Отлично. Подумаем об этом.
Допустим, у нас наложены некоторые ограничения на значение переменной color. Например, Вы хотите, чтобы переменная color могла принимать значения только от 1 до 10. Значения же не входящие в этот диапазон могут вызвать сбой программы или привести к нежелательным результатам. В этом случае будет не очень хорошо, если пользователю разрешено менять параметры напрямую. Верно? Даже, если Вы будете знать, что значения должны быть из промежутка от 1 до 10, другой человек, использующий Ваш код, может об этом и не подозревать. Выход: сделайте Вашу переменную private ("частной"), т.е. такой, что только самому классу будет дозволено ее изменять2:
Ключевое слово private называют "спецификатором доступа". Private указывает на то, что данная переменная доступна только изнутри объекта, а снаружи ее "не видно". Объект может изменить значение такой переменной посредством метода, но если попытаться обратиться к этой переменной с помощью прямого доступа:
... то в результате Вы получите ошибку, не зависимо от того, верное число или нет, т.к. спецификатор private не "позволит" Вам ее изменять таким образом. Такой подход предоставляет Вам возможность контролировать получаемые объектом значения и более четко определить их поведение. Теперь, Вы можете, например, проверить вводимое значение и вернуть сообщение об ошибке или описать специальное действие в случае неправильного ввода.
Семейство классов
Не утомились еще? Самое время хлебнуть холодного пивка3. Это всего лишь фундаментальные понятия об объектах!
Как Вы заметили (если Вы конечно творческая личность - что несомненно, раз Вы это читаете), объекты сами по себе обладают огромным потенциалом. Объекты позволяют разбить нашу задачу на более удобоваримые части. Тем не менее, трудности все же есть, т.к. теперь нам нужно управлять множеством объектов. Это приводит нас к следующей важной концепции объектно-ориентированного программирования: отношения между объектами.
Очень удобно проиллюстрировать объектные отношения на основе аналогии с машиной. Класс CarPart не дает нам полную картину, что же представляет собой деталь машины на самом деле. Учитывая то, что мы теперь знаем об объектах, мы, возможно, даже не будем использовать CarPart... вместо этого, мы опишем класс, например, SteeringWheel (руль). Это звучит более точнее и такой класс удобней использовать.
Фактически, лед тронулся. Мы уже мысленно построили отношения между CarPart и SteeringWheel. Действительно, SteeringWheel (руль) является разновидностью CarPart (детали). Верно? Так что, если класс CarPart опишет методы и свойства присущие всем возможным разновидностям деталей, а другие классы, такие как SteeringWheel, "расширят" его функциональность?
На языке программистов такие отношения называются "родительско-дочерние отношения". CarPart, в данном случае, играет роль "родителя" (или super класса) класса SteeringWheel. В Unreal Script дочерний класс объявляется следующим образом:
Видите ключевое слово expands? Оно означает что класс, который мы объявляем (SteeringWheel) является "дочерним" классом CarPart. Как только Unreal встретит expands, он сразу сформирует отношения между соответствующими классами.
Принцип I: Наследование
Что же нам дают эти родительско-дочерние отношения, нам, пытающимся решить поставленную задачу? Да это существенно упрощает нам жизнь! При установлении такого рода отношений между двумя классами, дочерний класс мгновенно "наследует" свойства и методы родителя. И все это без написания и строчки кода: SteeringWheel обладает всей функциональностью CarPart. Если класс CarPart имеет метод setColor(), то SteeringWheel также имеет его. Наследование распространяется на переменные, на методы и на состояния (states).
Такой подход позволяет нам построить то, что программисты называют "Иерархия объектов" (или "Семейство классов"). Это выглядит как генеалогическое дерево:
Object
| expanded by
Actor
| expanded by
CarPart
| expanded by
SteeringWheel
Object и Actor являются специальными классами в Unreal (подробнее см. "UnrealScript Language Reference"). Полное дерево классов в Unreal представляет собой огромную "паутину" взаимоотношений, которую, Вы только можете себе представить. В нашем примере, у нас простое отношение типа "is-a":
A SteeringWheel is a CarPart (Руль есть Деталь)
A CarPart is an Actor (Деталь есть Актер)
An Actor is an Object (Актер есть Объект)
Каждый следующий "слой" в дереве наследования расширяет функциональность предыдущего. Это позволяет нам без труда описывать сложные объекты в рамках "входящих" в него объектов. Очень важно понимать, что отношения не коммутативны (взаимнообратны). SteeringWheel (руль) всегда является CarPart (деталью), но CarPart (деталь) не всегда является SteeringWheel (рулем). Двигаясь вверх по иерархии, мы двигаемся к простому, вниз - к более специфичному. Надеюсь, понятно? Отлично!
Э-э-э! Секундочку... если мы строим машину (car) и машина сделана из деталей, где же сам класс Car? Вот мы и нарвались на различия во взаимоотношениях: "is-a" ("есть") против "has-a" ("имеет"). Ясно, что CarPart (деталь) не является Car (машиной). С другой стороны отношение "CarPart expands Car" будут также неверно. Поэтому, лучше всего, построить иерархию таким образом:
Object
|
Actor
/ \
Car CarPart
|
SteeringWheel
Класс Car "происходит" от класса Actor, и, при этом, не имеет прямого отношения с CarPart (Вы можете называть их братьями). Вместо этого, класс Car может содержать в себе переменные типа CarPart. В этом случае, мы имеем отношения "has-a" ("имеет"). Car (машина) имеет SteeringWheel (руль), но SteeringWheel (руль) не является Car (машиной). Если Вы создаете иерархию классов и запутались, то очень удобно представить отношения фразами "имеет" и "есть".
Как видно из вышесказанного, иерархия отношений позволяет нам делать интересные вещи. Если нам вдруг захотелось, например, расширить понятие о машине, мы можем добавить Vehicle (транспорт):
Object
|
Actor
/ \
Part Vehicle
/ | | \
CarPart AirPart Car Airplane
Правда круто! Не только потому, что это является удобным способом организовать и визуально представить объекты, но и потому, что в силу наследования, отпадает необходимость копирования и переписывания кода!
Принцип II: Полиморфизм
Поли что? Очередное словечко из лексикона этих сумасшедших программистов. (Если Вы до этих пор понимали все, что я пытался втолковать, значит, Вы являетесь больше программистом, чем сами об этом думаете) Полиморфизм - одна из фундаментальных основ объектно-ориентированного программирования. При наследовании, дочерний класс "перенимает" переменные, методы и состояния (states) родительского класса... но что если мы хотим изменить наследованные элементы? В примере с машиной, Вы, возможно, захотите написать класс Pedal (педаль), в котором определите метод PushPedal() (нажатие педали). Когда вызывается PushPedal(), этот метод производит какое-то действие (например, активирует тормоза). Если, затем Вы расширите класс Pedal новым классом, например, AcceleratorPedal (педаль газа), метод PushPedal(), мягко говоря, становится некорректным. При нажатии педали газа, явно не должны включаться тормоза! (Иначе у Вас будут большие проблемы с законом при релизе Вашей программы, уж поверьте мне).
В этом случае, Вы должны заменить унаследованное поведение педали другим. Это можно сделать посредством "полиморфизма" или "перегрузкой функции"4. Вы будете часто использовать этот прием, программируя на Unreal Script. Пояснение что же такое полиморфизм я позаимствовал у Tim Sweeney:
[Перегрузка функции] подразумевает под собой написание новой версии функции в подклассе (дочернем классе). Например, Вы пишете код для нового вида монстра - Demon. Класс Demon, который Вы создали, расширяет класс Pawn. Что происходит, когда Pawn видит игрока - вызывается функция [SeePlayer()] и Pawn начинает его атаковать. Неплохо, но что, если, скажем, Вы хотите по-своему определить поведение Demon в Вашем классе.
Для этого, просто переопределите эту функцию в дочернем классе. Когда создается объект этого класса, он будет обладать новым поведением, а не заимствованным у родителя. Если Вы хотите запретить переопределение функции подклассам, то воспользуйтесь ключевым словом final при объявлении метода:
Таким образом, Вы застрахуетесь от перегрузки функции в "производных" классах. Очень разумно использовать это для поддержки целостности поведения в Вашем коде. Tim Sweeney, также, указывает на то, что использование final повышает производительность в Unreal.
Заключение
Теперь Вы знакомы с фундаментальными основами объектно-ориентированного программирования и, я надеюсь, имеете хорошее представление об отношениях между объектами. Что же дальше?
Совет: программируйте. Погрузитесь в код, и не выныривайте из него, даже если обещания еды, сна и секса приняли вполне реальные очертания. Обыщите все дно. Или... Вы всегда можете обратиться к руководству "UnrealScript Language Reference" от Tim Sweeney. Там Вы найдете более детальное пояснение относительно синтаксиса присущего ОО в Unreal. В дополнение ко всему, я посоветую Вам найти другие ресурсы, касающиеся ОО логики и ООП. ООП также присущи тонкие моменты, которые можно только выучить. Некоторые из них не реализованы в Unreal, другие - реализованы. Некоторые являются всего лишь способом мышления.
Вот мы и пришли к заключительной точке. ОО является настолько путем мышления, насколько путем программирования. Попробуйте по пути в школу или когда едете на работу представить отношения между окружающими Вас вещами (дерево имеет листья, роза это цветок). Это усилит Ваше восприятие ОО логики. Создайте комплекс отношений в уме, и Вы без труда найдете способ переложить их в код.
Для тех, кто это понимает и наслаждается этим, программирование является, прежде всего, интеллектуальной, физической и духовной задачей. Это может звучать странно, но программирование затрагивает основные пути, какими мы мыслим и решаем проблемы. Если Вы можете думать "на" ОО, значит, Вам не грозят проблемы при решении задач ООП. Чем больше Вы будете использовать такой подход, тем больше Вы будете осознавать, что это реальность.
С помощью ОО, к сожалению, не все можно решить. Как и любой способ мышления, объектно-ориентированной парадигме присуще игнорирование некоторых моментов решения проблемы, связанное с желанием усилить аналогию с реальной системой. Скорее всего, Вы не встретитесь с подобной проблемой, программируя на Unreal Script. Во всяком случае, до тех пор, пока Вы не захотите написать чертовски навороченный мод.
Автор
© 1998-2002 Brandon Reinhart
Перевод сделан 32_Pistoleta.
Примечания
В ОО логике класс представляет собой описание того, как будет "выглядеть" вещь, если бы она была создана. Класс является общим шаблоном. Он определяет абстрактные свойства (например, деталь машины имеет свой цвет), но, обычно, не определяет реальное проявление этих свойств в природе (например, какого цвета деталь). Класс также определяет поведение объекта. Набор специальных функций однозначно указывает, как будет "вести" себя объект в Вашей программе. На языке программистов, такие абстрактные свойства называются "переменными экземпляра" (instance variables), а функции, описывающие поведение объекта - "методами" (method). Процесс создания объекта на основе класса называется "реализацией" (instantiation). Очень важно понимать, что класс не является объектом, а представляет собой шаблон, на основе которого эти объекты могут быть созданы. Когда Вы создаете объект (экземпляр класса), Вы создаете модель из шаблона.
Механика класса
В Unreal Script мы определяем классы посредством "объявления класса" (class declaration):
class MyClass expands MyParentClass; |
После того, как Вы объявили новый класс в Unreal Script, самое время определить переменные экземпляра. Все что Вам нужно для этого сделать - это указать список необходимых свойств:
var int color; // Номер цвета детали var byte manufacturer; // ID (ссылка на) производителя |
/////////////////////////////////////////////////// // Переменные экземпляра для MyClass |
Определение методов в новом классе очень похоже на объявление переменных: просто составьте список необходимых функций:
function doAThing() { // Выполнение некоторого кода UnrealScript } function doAnotherThing() { // Другая функция, которая что-то делает } |
В Unreal Script, создание объектов называется "spawning" (порождение). Вот как можно использовать функцию Spawn() для создания нового объекта из класса-шаблона:
var actor MyObject; // Переменная, содержащая (ссылающаяся на) объект MyObject = Spawn(MyClass); // Порождение объекта |
Объект является независимым контейнером данных, которые "висят" в памяти. Ключевым словом является именно независимость. Каждый объект выполняет свою работу. Если Вы описали класс MyBot и создали два объекта (экземпляра) из этого класса с именами BotA и BotB эти два объекта ничего друг о друге не знают и даже не подозревают о существовании друг друга. Это приводит нас к следующей концепции объектно-ориентированного программирования: объекты изменяют сами себя.
Когда создается объект он вставляется в хэш таблицу в памяти и ему присваивается индивидуальный ключ поиска, затем о нем забывается. Система находит объект по ключу в случае, если Вы хотите что-то с ним сделать, для всех остальных целей объект является "как бы" недоступным. Недоступность проявляется в том, что Вы не можете просто взять и поменять объект как обычную переменную. Вы не можете, например, открыть объект и изменить содержащиеся в нем переменные (это одно из основных отличий объектов от структур в языке С++). Вместо этого, Вы говорите объекту изменить самого себя. Это производится посредством методов.
Методы класса определяют, каким образом будет действовать объект после создания. Если Вы хотите изменить переменную экземпляра (объекта), Вам необходимо описать соответствующий метод, который позволяет это сделать. Наш класс CarPart может иметь, например, такой метод:
function setColor(int newColor) { color = newColor; } |
MyObject.setColor(15); // Говорим объекту, чтобы он вызвал метод setColor() |
Помните, я Вам говорил, что объекты изменяют сами себя? На самом деле это не совсем так. Я так говорил, т.к. хотел, чтобы Вы думали об объектах, как о независимых "существах" в Вашей программе. Говоря на чистоту, переменные экземпляра можно менять напрямую:
MyObject.color = 15; |
Допустим, у нас наложены некоторые ограничения на значение переменной color. Например, Вы хотите, чтобы переменная color могла принимать значения только от 1 до 10. Значения же не входящие в этот диапазон могут вызвать сбой программы или привести к нежелательным результатам. В этом случае будет не очень хорошо, если пользователю разрешено менять параметры напрямую. Верно? Даже, если Вы будете знать, что значения должны быть из промежутка от 1 до 10, другой человек, использующий Ваш код, может об этом и не подозревать. Выход: сделайте Вашу переменную private ("частной"), т.е. такой, что только самому классу будет дозволено ее изменять2:
var private int color; // Объявляем private переменную |
MyObject.color = 15; |
Семейство классов
Не утомились еще? Самое время хлебнуть холодного пивка3. Это всего лишь фундаментальные понятия об объектах!
Как Вы заметили (если Вы конечно творческая личность - что несомненно, раз Вы это читаете), объекты сами по себе обладают огромным потенциалом. Объекты позволяют разбить нашу задачу на более удобоваримые части. Тем не менее, трудности все же есть, т.к. теперь нам нужно управлять множеством объектов. Это приводит нас к следующей важной концепции объектно-ориентированного программирования: отношения между объектами.
Очень удобно проиллюстрировать объектные отношения на основе аналогии с машиной. Класс CarPart не дает нам полную картину, что же представляет собой деталь машины на самом деле. Учитывая то, что мы теперь знаем об объектах, мы, возможно, даже не будем использовать CarPart... вместо этого, мы опишем класс, например, SteeringWheel (руль). Это звучит более точнее и такой класс удобней использовать.
Фактически, лед тронулся. Мы уже мысленно построили отношения между CarPart и SteeringWheel. Действительно, SteeringWheel (руль) является разновидностью CarPart (детали). Верно? Так что, если класс CarPart опишет методы и свойства присущие всем возможным разновидностям деталей, а другие классы, такие как SteeringWheel, "расширят" его функциональность?
На языке программистов такие отношения называются "родительско-дочерние отношения". CarPart, в данном случае, играет роль "родителя" (или super класса) класса SteeringWheel. В Unreal Script дочерний класс объявляется следующим образом:
class SteeringWheel expands CarPart package(MyPackage); |
Принцип I: Наследование
Что же нам дают эти родительско-дочерние отношения, нам, пытающимся решить поставленную задачу? Да это существенно упрощает нам жизнь! При установлении такого рода отношений между двумя классами, дочерний класс мгновенно "наследует" свойства и методы родителя. И все это без написания и строчки кода: SteeringWheel обладает всей функциональностью CarPart. Если класс CarPart имеет метод setColor(), то SteeringWheel также имеет его. Наследование распространяется на переменные, на методы и на состояния (states).
Такой подход позволяет нам построить то, что программисты называют "Иерархия объектов" (или "Семейство классов"). Это выглядит как генеалогическое дерево:
Object
| expanded by
Actor
| expanded by
CarPart
| expanded by
SteeringWheel
Object и Actor являются специальными классами в Unreal (подробнее см. "UnrealScript Language Reference"). Полное дерево классов в Unreal представляет собой огромную "паутину" взаимоотношений, которую, Вы только можете себе представить. В нашем примере, у нас простое отношение типа "is-a":
A SteeringWheel is a CarPart (Руль есть Деталь)
A CarPart is an Actor (Деталь есть Актер)
An Actor is an Object (Актер есть Объект)
Каждый следующий "слой" в дереве наследования расширяет функциональность предыдущего. Это позволяет нам без труда описывать сложные объекты в рамках "входящих" в него объектов. Очень важно понимать, что отношения не коммутативны (взаимнообратны). SteeringWheel (руль) всегда является CarPart (деталью), но CarPart (деталь) не всегда является SteeringWheel (рулем). Двигаясь вверх по иерархии, мы двигаемся к простому, вниз - к более специфичному. Надеюсь, понятно? Отлично!
Э-э-э! Секундочку... если мы строим машину (car) и машина сделана из деталей, где же сам класс Car? Вот мы и нарвались на различия во взаимоотношениях: "is-a" ("есть") против "has-a" ("имеет"). Ясно, что CarPart (деталь) не является Car (машиной). С другой стороны отношение "CarPart expands Car" будут также неверно. Поэтому, лучше всего, построить иерархию таким образом:
Object
|
Actor
/ \
Car CarPart
|
SteeringWheel
Класс Car "происходит" от класса Actor, и, при этом, не имеет прямого отношения с CarPart (Вы можете называть их братьями). Вместо этого, класс Car может содержать в себе переменные типа CarPart. В этом случае, мы имеем отношения "has-a" ("имеет"). Car (машина) имеет SteeringWheel (руль), но SteeringWheel (руль) не является Car (машиной). Если Вы создаете иерархию классов и запутались, то очень удобно представить отношения фразами "имеет" и "есть".
Как видно из вышесказанного, иерархия отношений позволяет нам делать интересные вещи. Если нам вдруг захотелось, например, расширить понятие о машине, мы можем добавить Vehicle (транспорт):
Object
|
Actor
/ \
Part Vehicle
/ | | \
CarPart AirPart Car Airplane
Правда круто! Не только потому, что это является удобным способом организовать и визуально представить объекты, но и потому, что в силу наследования, отпадает необходимость копирования и переписывания кода!
Принцип II: Полиморфизм
Поли что? Очередное словечко из лексикона этих сумасшедших программистов. (Если Вы до этих пор понимали все, что я пытался втолковать, значит, Вы являетесь больше программистом, чем сами об этом думаете) Полиморфизм - одна из фундаментальных основ объектно-ориентированного программирования. При наследовании, дочерний класс "перенимает" переменные, методы и состояния (states) родительского класса... но что если мы хотим изменить наследованные элементы? В примере с машиной, Вы, возможно, захотите написать класс Pedal (педаль), в котором определите метод PushPedal() (нажатие педали). Когда вызывается PushPedal(), этот метод производит какое-то действие (например, активирует тормоза). Если, затем Вы расширите класс Pedal новым классом, например, AcceleratorPedal (педаль газа), метод PushPedal(), мягко говоря, становится некорректным. При нажатии педали газа, явно не должны включаться тормоза! (Иначе у Вас будут большие проблемы с законом при релизе Вашей программы, уж поверьте мне).
В этом случае, Вы должны заменить унаследованное поведение педали другим. Это можно сделать посредством "полиморфизма" или "перегрузкой функции"4. Вы будете часто использовать этот прием, программируя на Unreal Script. Пояснение что же такое полиморфизм я позаимствовал у Tim Sweeney:
[Перегрузка функции] подразумевает под собой написание новой версии функции в подклассе (дочернем классе). Например, Вы пишете код для нового вида монстра - Demon. Класс Demon, который Вы создали, расширяет класс Pawn. Что происходит, когда Pawn видит игрока - вызывается функция [SeePlayer()] и Pawn начинает его атаковать. Неплохо, но что, если, скажем, Вы хотите по-своему определить поведение Demon в Вашем классе.
Для этого, просто переопределите эту функцию в дочернем классе. Когда создается объект этого класса, он будет обладать новым поведением, а не заимствованным у родителя. Если Вы хотите запретить переопределение функции подклассам, то воспользуйтесь ключевым словом final при объявлении метода:
function final SeePlayer() |
Заключение
Теперь Вы знакомы с фундаментальными основами объектно-ориентированного программирования и, я надеюсь, имеете хорошее представление об отношениях между объектами. Что же дальше?
Совет: программируйте. Погрузитесь в код, и не выныривайте из него, даже если обещания еды, сна и секса приняли вполне реальные очертания. Обыщите все дно. Или... Вы всегда можете обратиться к руководству "UnrealScript Language Reference" от Tim Sweeney. Там Вы найдете более детальное пояснение относительно синтаксиса присущего ОО в Unreal. В дополнение ко всему, я посоветую Вам найти другие ресурсы, касающиеся ОО логики и ООП. ООП также присущи тонкие моменты, которые можно только выучить. Некоторые из них не реализованы в Unreal, другие - реализованы. Некоторые являются всего лишь способом мышления.
Вот мы и пришли к заключительной точке. ОО является настолько путем мышления, насколько путем программирования. Попробуйте по пути в школу или когда едете на работу представить отношения между окружающими Вас вещами (дерево имеет листья, роза это цветок). Это усилит Ваше восприятие ОО логики. Создайте комплекс отношений в уме, и Вы без труда найдете способ переложить их в код.
Для тех, кто это понимает и наслаждается этим, программирование является, прежде всего, интеллектуальной, физической и духовной задачей. Это может звучать странно, но программирование затрагивает основные пути, какими мы мыслим и решаем проблемы. Если Вы можете думать "на" ОО, значит, Вам не грозят проблемы при решении задач ООП. Чем больше Вы будете использовать такой подход, тем больше Вы будете осознавать, что это реальность.
С помощью ОО, к сожалению, не все можно решить. Как и любой способ мышления, объектно-ориентированной парадигме присуще игнорирование некоторых моментов решения проблемы, связанное с желанием усилить аналогию с реальной системой. Скорее всего, Вы не встретитесь с подобной проблемой, программируя на Unreal Script. Во всяком случае, до тех пор, пока Вы не захотите написать чертовски навороченный мод.
Автор
© 1998-2002 Brandon Reinhart
Перевод сделан 32_Pistoleta.
Примечания
- cleanSocks(): здесь под словом Socks подразумевалось Sockets (сокеты), но с носками звучит веселее 8)
- Вообще, это не совсем верно. Private не указывает на то, кто может управлять переменной. На самом деле private указывает, что свойство не видно снаружи объекта. Оно доступно только для внутренних структур объекта. Такой прием, позволяющий "спрятать" от внешних глаз переменную (и даже метод), называется "инкапсуляцией";
- В оригинальном тексте предлагали хлебнуть Dr. Pepper. Я позволил себе исправить это в соответствии с национальными интересами 8)
- Подобную процедуру еще часто называют "подавлением функции". Подавлять можно не только методы, но и переменные и состояния;
UnrealScript.ru - Объектно-ориентированная логика
unrealscript.narod.ru
Последнее редактирование: