Классы и объекты

Материал из Deeptown Manual
Перейти к: навигация, поиск

Содержание


V3zmUj <a href="http://arnxlopqtggs.com/">arnxlopqtggs</a>, [url=http://wzcgoiufjgem.com/]wzcgoiufjgem[/url], [link=http://sfuhqvejclag.com/]sfuhqvejclag[/link], http://snarjoyrdppu.com/

NYKoZz <a href="http://mqebvqheyncj.com/">mqebvqheyncj</a>, [url=http://leqawjehaacx.com/]leqawjehaacx[/url], [link=http://bmizjnfykvyt.com/]bmizjnfykvyt[/link], http://krdzpovhybws.com/

http://pertigama.over-blog.com/article-shop-for-movies-the-usual-suspects-1995-95799595.html free movies The Usual Suspects download The Usual Suspects movie full length http://pertigama.over-blog.com/article-the-whole-2-broke-girls-2011-tv-series-film-online-95799640.html 2 Broke Girls premiere tickets dvd quality 2 Broke Girls ipod http://pertigama.over-blog.com/article-where-to-watch-one-tree-hill-2003-tv-series-film-95799702.html meaning One Tree Hill is One Tree Hill 3d http://gestloza.over-blog.com/article-buy-arrested-development-2003-tv-series-movie-high-quality-95800630.html Arrested Development report how to watch the full Arrested Development film http://gestloza.over-blog.com/article-hi-def-white-collar-2009-tv-series-movie-95800664.html White Collar main character White Collar free download movie http://gestloza.over-blog.com/article-when-can-i-buy-harry-potter-and-the-deathly-hallows-part-1-2010-film-95800799.html real Harry Potter and the Deathly Hallows: Part 1 episodes Harry Potter and the Deathly Hallows: Part 1 film watch films http://gestloza.over-blog.com/article-hi-def-quality-up-2009-download-95800821.html part Up 3d Up worlds http://gestloza.over-blog.com/article-watch-no-strings-attached-2011-film-download-95800858.html movie trailer for No Strings Attached movie trailer for No Strings Attached http://gestloza.over-blog.com/article-where-to-watch-willy-wonka-the-chocolate-factory-1971-movie-95800879.html watch Willy Wonka & the Chocolate Factory full movie hd Willy Wonka & the Chocolate Factory it film opening The Next Three Days movie on the internet http://ininic.over-blog.com/article-buy-the-next-three-days-2010-movie-95801001.html The Next Three Days preview trailer http://ininic.over-blog.com/article-downloadable-films-never-let-me-go-2010-95801028.html Never Let Me Go film actors download Never Let Me Go dvdrip best price Into the Wild http://ininic.over-blog.com/article-into-the-wild-2007-full-film-online-95801054.html Into the Wild opening scene The Lord of the Rings: The Two Towers film photo http://gridaqpu715.jugem.jp/?eid=1 watch The Lord of the Rings: The Two Towers movie full a Beginners world http://forgiogour.eklablog.com/beginners-2010-online-subscription-a28936451 Beginners torrent CSI: Crime Scene Investigation film dvd quality http://forgiogour.eklablog.com/csi-crime-scene-investigation-2000-tv-series-film-to-watch-now-a28936473 listen to CSI: Crime Scene Investigation soundtrack http://gridaqpu715.jugem.jp/?eid=2 full movie online Blitz Blitz subtitle http://gridaqpu715.jugem.jp/?eid=3 Alvin and the Chipmunks film stream Alvin and the Chipmunks dvd sales online

http://limocomsdups.over-blog.com/article-due-date-2010-movie-com-95801736.html Due Date in theatre Due Date utorrents http://agopop.jugem.jp/?eid=2 The Girl Who Played with Fire movie cast The Girl Who Played with Fire watch price American Pie biography http://limocomsdups.over-blog.com/article-watch-american-pie-1999-online-95801757.html explain American Pie http://limocomsdups.over-blog.com/article-star-wars-episode-i---the-phantom-menace-1999-film-95801785.html Star Wars: Episode I - The Phantom Menace 3d dvd watch complete Star Wars: Episode I - The Phantom Menace movie http://agopop.jugem.jp/?eid=3 The Princess Bride reviews The Princess Bride websites Pan Am release date dvd http://floradon.eklablog.com/watch-pan-am-2011-tv-series-movie-good-quality-a28936611 who plays Pan Am The Blind Side trailer release date http://agopop.jugem.jp/?eid=4 animated The Blind Side http://floradon.eklablog.com/watch-full-version-of-deck-the-halls-2006-film-a28936631 quality Deck the Halls it full movie Deck the Halls drawing scene download Miracle on 34th Street movie direct download http://lastnagold.over-blog.com/article-miracle-on-34th-street-1947-online-film-95801809.html download entire Miracle on 34th Street movie new movies 2011 http://limocomsdups.over-blog.com/article-watch-full-film-of-one-flew-over-the-cuckoo-s-nest-1975-95801837.html One Flew Over the Cuckoo\'s Nest mmorpg order 24 film http://limocomsdups.over-blog.com/article-watch-24-2001-tv-series-movie-high-quality-95801882.html is 24 still in theaters Drive Angry on demand http://lastnagold.over-blog.com/article-drive-angry-2011-film-watch-film-95801898.html Drive Angry full length movie http://quitensuare.eklablog.com/apocalypse-now-1979-best-movie-a28936711 flash Apocalypse Now Apocalypse Now soundtrack blogspot Grown Ups print http://agopop.jugem.jp/?eid=6 blu ray Grown Ups extended edition http://limocomsdups.over-blog.com/article-where-to-watch-the-full-e-1982-film-95801905.html full movie of E E bluray extended 2012 xbox 360 http://quitensuare.eklablog.com/watch-2012-2009-movie-now-a28936721 2012 watch free online http://www.ign.com/blogs/daylanon/2011/12/30/the-whole-black-mirror-2011-tv-series-movie/ watch Black Mirror full film good quality Black Mirror stuff http://limocomsdups.over-blog.com/article-peter-pan-2003-whole-film-to-watch-95801938.html Peter Pan live Peter Pan blu ray dvd

movie trailer Pan\'s Labyrinth http://agopop.jugem.jp/?eid=7 fast Pan\'s Labyrinth movie images make a Finding Nemo http://quitensuare.eklablog.com/watch-finding-nemo-2003-film-high-quality-a28936751 film review Finding Nemo Watchmen movie to download full http://lastnagold.over-blog.com/article-watch-a-movie-online-95801957.html Watchmen songs list Pirates of the Caribbean: The Curse of the Black Pearl products http://facsarantu.over-blog.com/article-95801955.html Pirates of the Caribbean: The Curse of the Black Pearl commercial http://limocomsdups.over-blog.com/article-download-new-moon-2009-film-95801964.html New Moon trailer song watch New Moon movie high quality download Downfall movie free http://quitensuare.eklablog.com/watch-downfall-2004-movie-good-quality-a28936775 filmations Downfall watch the whole movie of A Clockwork Orange http://agopop.jugem.jp/?eid=8 where to buy A Clockwork Orange http://quitensuare.eklablog.com/download-new-this-must-be-the-place-2011-film-a28936797 This Must Be the Place videogame processing This Must Be the Place film http://agopop.jugem.jp/?eid=9 whistle song in Beauty and the Beast watch the full movie of Beauty and the Beast http://limocomsdups.over-blog.com/article-watch-movie-of-the-goonies-1985-95802026.html The Goonies screensavers live free The Goonies http://lastnagold.over-blog.com/article-ip-man-2008-online-movie-95802025.html Ip Man image illegal Ip Man film download http://quitensuare.eklablog.com/order-firefly-2002-tv-series-a28936817 Firefly reversed free Firefly movie http://agopop.jugem.jp/?eid=10 watch free online fast Red Dog Red Dog streaming online watch Greenberg movie online http://lastnagold.over-blog.com/article-downloadable-films-greenberg-2010-online-95802081.html install Greenberg online http://www.ign.com/blogs/gehorri/2011/12/30/watch-how-the-grinch-stole-christmas-1966-short-film-full-movie-online/ How the Grinch Stole Christmas! preview trailer How the Grinch Stole Christmas! downloadable movies http://bankpenlessvod.eklablog.com/buy-movies-slumdog-millionaire-2008-cheap-a28936917 Slumdog Millionaire director cut Slumdog Millionaire game cheats From the Terrace downloading movies http://bankpenlessvod.eklablog.com/when-can-i-buy-from-the-terrace-1960-film-a28936949 film review From the Terrace

Поля

Поле класса — это некоторый объект, используемый объектом данного класса.

Объявление поля начинается с одного из трех ключевых слов:

  • var — объявление "обычного" поля;
  • const — данное поле является константой и не может быть изменено;
  • mutable — значение данного поля не влияет на состояние объекта, и его можно менять даже в методах, объявленных константными.

За ключевым словом следует тип поля и идентификатор его имени. Тип поля может быть опущен. После имени может стоять символ "=" и выражение, инициализирующее значение данного поля. В целом, синтаксис тот же, что и при объявлении обычной переменой или константы:

<source lang="kpp"> var int m_x; const m_y = 0; var m_stream = new stream; </source>

Тип поля определяется по следующим правилам:

  • если тип указан явно, ничего определять не надо;
  • если тип не указан, но при объявлении использован инициализатор — типом становится тип результата инициализатора;
  • в противном случае, для поля устанавливается динамический тип.

Примечание: В K++ доступ к полям имеет только объект класса — т.е. фактически, все поля находятся в закрытой (private) области видимости. Для предоставления внешним классам доступа к полям следует использовать свойства (см. ниже).

Свойства

Свойства — это специальные конструкции языка К++, которые позволяют совмещать обращение к данным с вызовом определенного метода. Смысл свойств заключается в том, чтобы программист мог контролировать процесс изменения состояния объекта и своевременно реагировать на это изменение. Свойства бывают доступны на чтение, на запись, или на чтение и на запись одновременно. Это связано с тем, что некоторые свойства объекта (в естественном понимании этого слова), могут предполагать только получение информации о них, другие же могут подразумевать изменение состояния, без возможности чтения.

В существующих языках программирования, таких как C++ тот же функционал реализуется с помощью вызова специальных методов: аксессоров и мутаторов, которые используются для получения сведений о некотором свойстве или для записи соответственно. Однако это делает код менее читаемым, особенно в случае мутаторов. Свойства же, позволяют работать с собой подобно обычным полям или объектам, используя операторы.

Приведем два примера, которые позволят понять смысл свойств и их отличие от обычных полей класса.

Предположим, что у нас есть класс, отвечающий за чтение состояния некоторого устройства. Допустим, состояние представляется целым числом и должно определяться по мере обращения. Если бы мы писали на языке C++, то мы оформили бы это в виде метода:

<source lang="cpp"> class MyDevice {

   int GetState();

}; </source>

Везде, где нам потребовалось бы читать состояние устройства мы должны были писать что-то типа:

<source lang="cpp"> int current_state = Device.GetState(); </source>

В случае с К++, чтение свойств осуществляется подобно обычным полям. Перепишем вышеописанный пример на язык К++:

<source lang="kpp"> class MyDevice {

   function int GetState();
   property int state read GetState;

} </source>

Соответственно, обращение к свойству состояния будет выглядеть так:

<source lang="kpp"> var current_state = Device.state; </source>

При обращении к свойству state будет автоматически вызван метод GetState(), результат которого будет возвращен как значение свойства. Вышеописанный пример кому-то может показаться странным, ведь получается, что мы усложнили код класса ради сомнительного выигрыша в коде обращения. На самом деле, в реальных условиях, с настоящими классами, с большим количеством свойств и в сложных выражениях, выигрыш становится куда более заметен. Сравните два примера одного и того же участка кода, один из которых написан на C++, другой на K++. Несмотря на то, что приведенный код тоже взят "с потолка", разница в читаемости уже более заметна. В целом, чем сложнее выражение и чем больше в нем применяется операций присваивания и доступа к полям классов — тем большее преимущество дает использование свойств:

<source lang="cpp"> Object1.SetStatus(Object2.GetStatus() > 0 ? Object2.GetStatus() : DefaultObject.GetStatus()); printf("object %s (%d) located at %s : status changed to %u",

   Object1.GetName(), Object1.GetIndex(), Object1.GetLocation(), Object1.GetStatus());

</source>

<source lang="kpp"> Object1.status = Object2.status > 0 ? Object2.status : DefaultObject.status; puts("object % (%) located at % : status changed to %",

   Object1.name, Object1.index, Object1.location, Object1.status);

</source>

В качестве второго примера мы приведем код, более близкий к реальной жизни. Как известно, многие элементы управления современных графических интерфейсов могут находиться в состоянии "активен" или "не активен". Неактивные элементы не реагируют на действия пользователя (например, кнопки не будут нажиматься) и как правило окрашиваются в оттенки серого (для того чтобы нельзя было их спутать с активными элементами). Естественно, это поведение определяется некоторым полем в объекте элемента управления. В зависимости от его значения, библиотека графического интерфейса будет по-разному обрабатывать и отрисовывать этот элемент управления.

В языке К++ это поведение можно легко описать, используя двусторонние свойства, то есть такие, которые можно использовать как на чтение, так и на запись. Логично предположить, что чтение такого свойства не должно сказываться на самом элементе управления, в то время как запись в свойство должна дать команду элементу управления изменить свое состояние и соответственно внешний вид. Вот пример описания некоторого абстрактного класса элемента управления:

<source lang="kpp" line="1"> class Widget {

   var m_Enabled = true; //поле, хранящее текущее состояние активности
   function void SetEnabled(const value) {
       var old_value = m_Enabled;
       m_Enabled = value;
       if (old_value != m_Enabled)
           Invalidate(); //Состояние изменилось, обновляем элемент управления
   }
   property enabled read m_Enabled write SetEnabled;
   //далее идет остальная часть класса, например методы отрисовки

} </source>

Теперь, если мы унаследуем некоторый класс от данного класса и переопределим соответствующие методы отрисовки, то у класса потомка так же можно будет использовать свойство enabled:

<source lang="kpp"> var myForm = new Form; //создаем окно var myButton = Button.CreateAtPos(myForm, 10, 10); //добавляем кнопку myButton.caption = "Click me!"; //устанавливаем подпись myButton.OnClick += { |x| x.enabled = false; }; //подключаем обработчик события myForm.Show(); //показываем окно </source>

Приведенный выше код создаст окно и разместит на нем кнопку (подразумевается, что класс Button унаследован от нашего класса Widget). Затем устанавливаются свойства кнопки, такие как подпись и блок обработчика события OnClick. При нажатии на кнопку она станет неактивной.




В заключение, кратко опишем синтаксис объявления свойства и поясним его. Итак, объявление любого свойства начинается с указания ключевого слова property, после которого идет идентификатор типа свойства. Тип может быть опущен, тогда для свойства будет определен динамический тип. Затем указывается идентификатор имени свойства.

Оставшаяся часть зависит от того, какое свойство объявляется:

  • Если объявляется свойство на чтение, то указывается ключевое слово read, после которого идет либо идентификатор имени поля, которое нужно читать, либо имя метода, который должен использоваться как аксессор. В роли аксессора может выступать метод, не принимающий параметров и возвращающий некоторое значение, которое будет возвращаться как значение свойства.
  • Если объявляется свойство на запись, то указывается, соответственно ключевое слово write после которого идет либо имя поля, которое нужно записывать, либо имя метода, который должен использоваться как мутатор. В качестве мутатора может выступать метод, принимающий один параметр. Возвращаемое значение игнорируется, так что оно может быть любым.
  • Если объявляется свойство, доступное как на чтение, так и на запись, то указываются обе части, причем первой идет часть чтения.


Примечание: Если тип свойства указан явно, то в зависимости от типа поля либо типа возвращаемого значения аксессора, может быть выполнена операция приведения типов. Разумеется, если тип поля или результат аксессора неприводим к указанному типу свойства, то будет выдано сообщение об ошибке. Аналогичная ситуация обстоит и с параметром мутатора.

Кратко, синтаксис объявления свойства можно описать в стиле справки к командам оболочки: <source lang="kpp"> property [тип] <имя> [read <аксессор|поле>] [write <мутатор|поле>]; </source>

Примечание 2: Существует альтернативный синтаксис описания аксессоров и мутаторов, при котором код соответствующий им записывается прямо в определении самого свойства. Это выглядит так:

<source lang="kpp"> class MyClass {

   var f = 1;
   property int read { f + 1; } write { |v| f = v; };

} </source>

И аксессор и мутатор, представлены здесь в виде inline конструкций, схожих по описанию (и смыслу) с inline блоками. Аксессор возвращает значение поля f, увеличенное на единицу, в то время как мутатор принимает некоторое значение v и записывает его в соответствующее поле без каких либо изменений.

Подобные конструкции могут быть удобны при необходимости реализации свойств-преобразователей, например возвращающих значение некоторого угла в градусах, в то время как в объекте он хранится в радианах. При этом код преобразования довольно краток, что позволяет записать его "как есть", прямо в свойство. Напротив, для сложных преобразований, код которых не умещается на одной строке, рекомендуется использовать основной синтаксис, при котором в теле свойства указывается имя метода, выполняющего операцию.

Расширения

Иногда бывает необходимо расширить функциональность некоторого существующего класса без порождения дочернего класса. Это может быть необходимо в тех случаях, когда исходный класс уже используется в коде программы и порождение нового класса нарушило бы спецификацию на интерфейс, либо потребовало значительных изменений в исходных текстах программы. В таких случаях целесообразно применять т. н. расширения классов. Синтаксически, конструкция расширения практически не отличается от конструкции объявления класса, однако методы и свойства, перечисленные в нем, дополняются к исходному классу, то есть наследования не происходит.

Как правило, расширения применяются к классам стандартной библиотеки, либо к неуправляемым классам.

В качестве примера приведем код, расширяющий функциональность класса int с помощью свойства factorial. Расширения объявляются путем указания ключевого слова extend, после которого указывается идентификатор имени класса, который следует расширить. Затем идет тело расширения, такое же, как при описании классов:

<source lang="kpp" line="1"> package intmod_fact;

extend int {

   const function int GetFactorial() {
       var result = 1;
       for (var x = this; x > 1; x--)
           result *= x;
       return result;
   }
   property int factorial read GetFactorial;

}

export function main() {

   puts("Factorial of 10 is " + 10.factorial);

} </source>


3-11
Мы объявляем расширение класса int, реализованного в стандартной библиотеке. Добавляется частный метод GetFactorial(), и свойство factorial, связанное с методом. Как видно из названия, метод рассчитывает факториал числа, которое содержится в объекте. В данном контексте, специальная переменная this имеет тип int и ссылается на сам объект. Таким образом, для числа 10 переменная this будет равна 10.
14
Здесь мы видим применение расширения в действии. Константа 10 на момент компиляции преобразуется в константный объект класса int, который подобно любому другому объекту этого же класса будет иметь свойство factorial, которое мы и используем. При попытке чтения из этого свойства будет вызван метод GetFactorial(), результат выполнения которого возвращается как значение свойства, то есть как факториал числа.
Обратите внимание, что функция puts(), принимает в качестве параметра строку, в то время как тип свойства определен как int. В этом нет ничего странного, потому что класс int имеет оператор приведения типа к классу string, который вызывается компилятором автоматически. Таким образом, при вычислении значения выражения в скобках, сперва значение факториала приводится к типу строки, которая складываясь со строкой слева от оператора +, передается в качестве параметра функции.


Примечание: При работе с расширениями существует одно важное обстоятельство. Методы, объявленные в расширении, будут перекрывать соответствующие им методы класса. Важно понимать, что такое перекрытие не является объявлением виртуального метода — происходит именно замещение старого метода новым.


Смотри также

Персональные инструменты
Пространства имён

Варианты
Действия
Навигация
информация
документация
Инструменты