Руководство по actionscript. часть 1, стр. 037

Class НекийКласс { public function НекийКласс ( ) { var идентификатор = значение:

}

}

В этом коде идентификатор представляет имя локальной переменной, а значение — значение, ассоциированное с этой переменной. Знак равенства и элемент значение называют инициализатором переменной, поскольку они определяют исходное значение переменной.

_а_

Я Процесс ассоциирования переменной со значением называется присваиванием, установкой или записью значения переменной.

Если инициализатор переменной не указан, то компилятор языка ActionScript автоматически присваивает переменной значение по умолчанию, соответствующее ее типу. Эти значения будут рассмотрены в гл. 8.

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

Для обращения к объекту класса VirtualPet, который был создан ранее в конструкторе класса VirtualZoo, создадим локальную переменную. Локальной переменной присвоим имя pet, а для связывания объекта VirtualPet с этой переменной воспользуемся инициализатором. Привожу код:

package zoo { public class VirtualZoo { public function VirtualZoo ( ) { var pet = new VirtualPet;

}

}

}

Теперь, когда локальная переменная pet связана с объектом VirtualPet, она может быть использована для обращения к объекту и, следовательно, для управления им. Однако в настоящий момент объект Vi г tua 1 Ре t не может выполнять никакие действия, поскольку его функциональность еще не запрограммирована. Способы устранения этого недостатка будут рассмотрены в разд. «Параметры и аргументы конструктора», в котором я также расскажу, как предоставить животным возможность иметь имена.

Переменные экземпляра

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

Переменная экземпляра — это переменная, принадлежащая определенному объекту. Обычно каждая переменная экземпляра описывает некую характеристику объекта, к которому принадлежит. Например, переменной экземпляра может являться идентификатор width, связанный со значением 150, которое определяет ширину кнопки интерфейса, или идентификатор shippingAddress, связанный со значением ул. Некая, 34, которое определяет адрес доставки объекта заказанного товара.

Руководство по actionscript. часть 1, стр. 038

Как видно из следующего обобщенного кода, переменные экземпляра создаются с помощью размещаемых непосредственно в описании класса описаний переменных:

class НекийКласс { var идентификатор = значение:

}

Добавление описания переменной экземпляра в описание класса приводит к автоматическому присоединению этой переменной к каждому экземпляру данно-

го класса. Как и в случае с локальными переменными, инициализатор описания переменной экземпляра задает исходное значение для создаваемой переменной. Однако, поскольку в переменных отдельно взятого экземпляра класса хранятся его собственные значения, исходное значение переменной экземпляра зачастую не указывается и присваивается позднее уже при выполнении программы.

В качестве примера добавим переменную экземпляра в класс VirtualPet. Она позволит отслеживать имя каждого объекта VirtualPet. Переменную экземпляра назовем именем pet Name:

package zoo { internal class VirtualPet { var petName = «Unnamed Pet»;

}

}

В результате использования приведенного кода переменная экземпляра petName будет автоматически присоединена к каждому новому экземпляру класса Vi г tua 1 Реt. Исходным значением переменной petName для всех экземпляров класса VirtualPet будет являться фраза Unnamed Pet. Тем не менее после создания экземпляра класса VirtualPet переменной petName может быть присвоено новое, индивидуальное значение.

Для присвоения переменной экземпляра нового значения используется следующий обобщенный код:

объект. переменнаяЭкземпляра = значение

Здесь объект — это объект, переменной экземпляра которого присваивается значение; переменнаяЭкземпляра — это одна из переменных экземпляра объект (описанных в классе объекта); значение — это присваиваемое значение.

Воспользуемся описанной методикой, чтобы присвоить какое-либо имя объекту VirtualPet, созданному ранее в конструкторе класса VirtualZoo. Привожу код описания класса VirtualZoo, который содержит все предыдущие изменения:

package zoo { public class VirtualZoo { public function VirtualZoo ( ) { var pet = new VirtualPet;

}

}

}

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

pet

Затем ставится точка:

pet.

После этого записывается имя переменной экземпляра, значение которой нужно изменить — в данном случае petName:

pet. petName

В конце ставится знак = и указывается значение, которое необходимо присвоить переменной экземпляра. В нашем примере применим значение Stan:

pet. petName = «Stan»

Разве это не мило? Теперь у нашего животного появилась кличка. Мы делаем успехи.

Ниже приведен измененный код описания класса VirtualZoo:

package zoo { public class VirtualZoo { public function VirtualZoo ( ) { var pet = new VirtualPet: pet. petName = «Stan»;

}

}

}

Обратите внимание, что в предыдущем коде значение переменной экземпляра petName, описанной в классе VirtualPet, присваивается через экземпляр класса VirtualPet, принадлежащего классу VirtualZoo. Следовательно, коду в классе VirtualZoo доступна переменная экземпляра petName. Когда класс разрешает доступ из других классов к своим переменным экземпляра, он позволяет этим классам вносить изменения в характеристики своих экземпляров.

Руководство по actionscript. часть 1, стр. 039

Имя животного — это характеристика, которая естественным образом пригодна для внешнего изменения. Тем не менее некоторые переменные экземпляра могут представлять характеристики, которые не должны изменяться за пределами класса, содержащего описание данных переменных. Например, далее будет создана переменная экземпляра caloriesPerSecond, определяющая скорость, с которой у того или иного животного переваривается пища. Если переменной caloriesPerSecond присвоить слишком маленькое или слишком большое значение, то животное может постоянно хотеть есть или, наоборот, никогда не проголодаться. Поэтому, чтобы внешний код не смог присвоить неприемлемое значение переменной caloriesPerSecond, необходимо ограничить доступ к этой переменной. Для этого применяются модификаторы управления доступом.

Модификаторы управления доступом для переменных экземпляра. Модификатор управления доступом переменной экземпляра определяет уровень доступа к этой переменной в программе. Для описаний переменных экземпляра существуют следующие модификаторы управления доступом: public, internal, protected и private.

Модификаторы pub lie и internal для переменных экземпляра обладают таким же эффектом, что и для классов. Переменная экземпляра, объявленная с использованием модификатора public, может быть доступна как внутри, так и снаружи пакета, в котором была описана; переменная экземпляра, объявленная с исполь-

Руководство по actionscript. часть 1, стр. 040

Зованием модификатора internal, может быть доступна только внутри пакета, в котором была описана.

Модификаторы protected и private накладывают еще большие ограничения, чем модификатор internal. Переменная экземпляра, объявленная с использованием модификатора protected, может быть доступна только для кода класса, содержащего описание этой переменной, или для кода потомков этого класса (мы еще не рассматривали наследование, поэтому, если вы незнакомы с объектно-ориентированным программированием, пока не обращайте внимания на этот модификатор). Переменная экземпляра, объявленная с использованием модификатора private, может быть доступна только для кода класса, содержащего описание этой переменной. Если при объявлении переменной никакой модификатор не указан, то используется модификатор internal (доступ внутри пакета).

Модификаторы управления доступом для переменных экземпляра перечислены в табл. 1.2.

Таблица 1.2. Модификаторы управления доступом переменной экземпляра

Атрибут

Размещение кода public internal protected private

Код в классе, содержащем описание переменной Доступна Доступна Доступна Доступна

Код в потомке класса, содержащего описание переменной Доступна Доступна Доступна Недоступна

Код в другом классе, принадлежащем пакету с описанием переменной Доступна Доступна Недоступна Недоступна

Код не принадлежит пакету с описанием переменной Доступна Недоступна Недоступна Недоступна

Если для описания переменных экземпляра класса использовать модификатор private, то информация каждого экземпляра будет полностью закрыта для случайного изменения, что позволит исключить зависимость внешнего кода от внутренней структуры класса и избежать случайного присваивания некорректных значений переменным экземпляра. Как правило, для каждой переменной экземпляра явно указывают модификатор управления доступом.

Использование модификатора public для описания переменных экземпляра является нежелательным, если это не заложено в архитектуру класса, однако если вы не уверены в том, какой модификатор управления доступом использовать, то его применение становится наиболее предпочтительным. Впоследствии, если понадобится, уровень доступа к переменной экземпляра может быть легко изменен, тем самым она станет более доступной. Если же переменная экземпляра будет описана с использованием модификатора public и внешний код уже использует эту переменную, то изменить модификатор управления доступом на private будет достаточно сложно.

Руководство по actionscript. часть 1, стр. 041

В текущей версии нашего приложения, создающего виртуальный зоопарк, к переменной экземпляра petName происходит обращение как из класса VirtualPet, так и из класса VirtualZoo, поэтому мы должны описать переменную petName

с использованием модификатора управления доступом internal, как показано в следующем коде:

package zoo { internal class VirtualPet { internal var petName = «Unnamed Pet»;

}

}

Обратите внимание, что описание переменной экземпляра с использованием атрибута internal аналогично описанию переменной без использования какого-либо модификатора управления доступом (поскольку модификатор internal применяется по умолчанию).

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

В настоящий момент структура класса VirtualPet допускает возможность присваивания значения переменной petName каждого объекта VirtualPet по желанию. Однако если необходимо гарантировать, что имя будет присвоено каждому животному, то можно использовать параметры конструктора, которые описываются в следующем разделе.

Параметры и аргументы конструктора

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

При создании параметров конструктора вместо ключевого слова var между круглыми скобками описания функции конструктора просто указывается желаемое имя и инициализатор переменной, как показано в следующем обобщенном коде:

class НекийКласс { function НекийКласс {идентификатор = значение) {

)

}

В данном коде идентификатор — это имя параметра конструктора, а значение — исходное значение параметра.

Если возникает необходимость описать несколько параметров в методе-конструкторе, то их имена перечисляются через запятую, как показано в обобщенном коде ниже (обратите внимание на разрывы строк, которые не только допустимы, но и широко распространены):

class НекийКласс { function НекийКласс {идентификатор! = значение1, идентификатор2 = значение2,

идентификаторЗ = значвнивЗ) {

}

}

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

new НекийКласс(значение1, значение2, значениеЗ)

В этом коде значение^ значение2 и значениеЗ — это значения, присваиваемые в указанном порядке параметрам метода-конструктора класса НекийКласс. Значение, присваиваемое параметру конструктора при создании объекта (как показано в предыдущем коде), называется аргументом конструктора. Использование аргумента конструктора в качестве значения параметра конструктора называется передачей этого значения конструктору.

Руководство по actionscript. часть 1, стр. 042

Если описание параметра конструктора не содержит инициализатора переменной, то исходное значение этого параметра указывается через аргумент конструктора. Такой параметр называется обязательным параметром конструктора. Следующий обобщенный код демонстрирует создание класса с одним обязательным параметром конструктора (обратите внимание, что описание параметра не содержит инициализатора переменной):

class НекийКласс { function НекийКласс (обязательныйПараметр) { }

}

Любой код, создающий экземпляр предыдущего класса, обязательно должен указывать значение параметра обязательныйПараметр с помощью аргумента конструктора, как показано ниже:

new НекийКласс(значение)

Отсутствие аргумента конструктора для обязательного параметра приведет к ошибке либо на этапе компиляции программы (если для компиляции выбран строгий режим), либо на этапе выполнения программы (если программа была откомпилирована в стандартном режиме). Различия между строгим и стандартным режимами компиляции будут рассмотрены в гл. 7.

Ш4_ Q При создании нового объекта без аргументов конструктора некоторым программистам 1 нравится оставлять пустые круглые скобки. Например, многие разработчики предпочи-— тают записывать

new Virtual Pet( ) а не

new VirtualPet

Выбор формата целиком и полностью является вопросом стиля. Язык ActionScript допускает использование обоих этих форматов. Тем не менее в среде программистов на языке ActionScript большее предпочтение отдается первому стилю (со скобками), нежели второму (без скобок). Поэтому начиная с этого момента при создании новых объектов в примерах кода из данной книги будут всегда использоваться круглые скобки, даже при отсутствии аргументов конструктора.

Руководство по actionscript. часть 1, стр. 043

Используя в качестве примера предыдущий обобщенный код, описывающий метод-конструктор класса с параметром, добавим новый метод-конструктор в класс VirtualPet и опишем один обязательный параметр конструктора — name. Значение параметра name будет присвоено переменной экземпляра petName каждого объекта VirtualPet.

Рассмотрим основной код, содержащий описание нового метода-конструктора без каких-либо инструкций:

package zoo { internal class VirtualPet { internal var petName = «Unnamed Pet»;

public function VirtualPet (name) {

}

}

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

package zoo { public class VirtualZoo { public function VirtualZoo ( ) { var pet = new VirtualPet; pet. petName = «Stan»;

}

}

}

Это же обновленная версия, в которой значение Stan передается конструктору класса VirtualPet, а не присваивается переменной petName созданного экземпляра:

package zoo { public class VirtualZoo { public function VirtualZoo ( ) { var pet = new VirtualPetC’Stan»);

}

}

}

В этом коде при создании экземпляра класса VirtualPet выполняется конструктор этого класса и аргумент конструктора Stan присваивается параметру name. Из этого следует, что внутри конструктора класса VirtualPet параметр name можно использовать для присваивания значения Stan переменной экземпляра petName нового объекта VirtualPet. Для этого необходимо указать значение переменной petName, используя выражение идентификатора.

Выражения и выражения идентификатора рассматриваются в следующем разделе.

Выражения

Представление значения в исходном коде программы на ActionScript называется выражением. Например:

new Date( )

Здесь new — выражение, представляющее новый объект (в данном случае объект Date).

Подобным же образом следующий код демонстрирует константное выражение, представляющее объект Number со значением 2.5:

2.5

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

Руководство по actionscript. часть 1, стр. 044

К примеру, оператор умножения, используемый для нахождения произведения двух чисел, записывается с помощью символа *. Следующий код демонстрирует составное выражение для умножения числа 4 на число 2,5:

4 * 2.5

При выполнении этого кода вычисляется результат произведения и все составное выражение (4 * 2.5) заменяется одним результатом вычисления (10). Процесс определения значения выражения называется его вычислением.

С полным списком операторов языка ActionScript можно ознакомиться в гл. 10.

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

Для примера рассмотрим составное выражение, в котором два значения, представленные именами переменных, перемножаются:

quantity * price

Переменные quantity и price являются своего рода контейнерами для значений, которые будут определены в процессе выполнения программы. Значение переменной quantity, например, может задаваться пользователем, а значение переменной price может быть получено из базы данных. Далее предположим, что переменной quantity присвоено значение 2, а переменной price — значение 4.99. При вычислении выражения quantity * price программа заменит имя переменной

quantity значением 2, а имя переменной price — значением 4 . 9 9. Таким образом, в процессе вычисления это выражение будет заменено следующим:

2 * 4.99

Окончательным результатом выражения является значение 9.98.

Л_

Говоря формальным языком, выражение, состоящее только из одного имени переменной, например quantity, называется выражением идентификатора.

Теперь попробуем применить выражение идентификатора в программе по созданию виртуального зоопарка.

Присваивание одной переменной значения другой переменной

В процессе написания кода программы мы остановились на создании метода-конструктора для класса VirtualPet. Метод-конструктор описывает единственный параметр name, значение которого определяется во внешнем коде, отвечающем за создание объекта в классе VirtualZoo. Ниже представлен исходный код классов VirtualPet и VirtualZoo, включающий в себя все произведенные ранее изменения:

Руководство по actionscript. часть 1, стр. 045

// Класс VirtualPet package zoo { internal class VirtualPet { internal var petName = «Unnamed Pet»;

public function VirtualPet (name) { }

}

}

// Класс VirtualZoo package zoo { public class VirtualZoo { public function VirtualZoo ( ) { var pet = new VirtualPetC’Stan»):

}

}

}

Теперь, после того как мы ознакомились с процессом применения переменных в выражениях, параметр name может быть использован для присвоения значения Stan переменной экземпляра petName нового объекта VirtualPet.

Как нам уже известно, чтобы присвоить новое значение переменной экземпляра, используется следующий обобщенный код:

объект. переменнаяЭкземпляра = значение

В соответствии с этим кодом, чтобы присвоить значение переменной, сначала необходимо указать объект. В данном случае таким объектом является создаваемый экземпляр класса VirtualPet. Для обращения к нему используется ключевое слово this — автоматически передаваемый параметр, значением которого является создаваемый объект.

_j$_

йЪь щ В теле метода-конструктора создаваемый объект называется текущим. Для обращения ¦г? Л к нему применяется ключевое слово this.

После ключевого слова this ставится точка, а затем указывается имя переменной экземпляра, которой необходимо присвоить значение, — в данном случае petName.

this. petName

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

this. petName = value

В нашем случае присваиваемым значением является значение параметра name. Таким образом, вместо слова value просто подставляется имя параметра name:

this. petName = name

На этапе выполнения среда Flash (в которой выполняется программа) заменит параметр name из предыдущего кода значением, переданным конструктору класса VirtualPet. Это значение впоследствии будет присвоено переменной экземпляра petName.

Код класса VirtualPet с внесенными изменениями выглядит следующим образом:

package zoo { internal class VirtualPet { internal var petName = «Unnamed Pet»;

public function VirtualPet (name) { this. petName = name;

}

}

}

Теперь, когда значение переменной экземпляра petName присваивается в конструкторе класса VirtualPet, ненужное исходное значение Unnamed Pet, указанное в описании переменной petName, может быть удалено. Описание переменной petName до настоящего момента выглядело следующим образом:

internal var petName = «Unnamed Pet»;

После изменений описание этой переменной примет следующий вид (обратите внимание на отсутствие инициализатора переменной):

package zoo { internal class VirtualPet { internal var petName;

}

public function VirtualPet (name) { this. petName = name;

}

Выражение, которое используется для присваивания значения переменной, например this. petName = name, называется выражением присваивания. В качестве знака равенства в таких выражениях применяется оператор, называемый оператором присваивания.

Копии и ссылки. В предыдущем разделе был описан процесс присваивания значения одной переменной другой. В частности, переменной экземпляра petName было присвоено значение параметра name. Вот этот код:

this. petName = name;

Результат присваивания значения одной переменной другой зависит от типа присваиваемого значения.

В случаях, когда значением переменной-источника в выражении присваивания является экземпляр класса String, Boolean, Number, int или uint, среда выполнения создает копию этого значения и присваивает созданную копию целевой переменной. После окончания процедуры присваивания в системной памяти образуются две независимые версии исходного значения — само исходное значение и его копия. Переменная-источник указывает, или ссылается, на первоначальное значение в памяти. Целевая переменная ссылается на новое значение в памяти.

В других случаях, когда значением переменной-источника в выражении присваивания выступает экземпляр пользовательского класса или экземпляр предопределенного класса языка ActionScript, за исключением классов String, Boolean, Number, int или uint, программа связывает вторую переменную непосредственно со значением первой. После присваивания в памяти будет существовать только одна копия значения, на которую будут ссылаться обе переменные. В подобной ситуации говорят, что переменные совместно используют ссылку на один объект в памяти. Очевидно, что изменения, вносимые в объект через первую переменную, будут доступны и для второй переменной. Например, рассмотрим код, в котором создаются две локальные переменные — а и Ь, после чего значение переменной а присваивается переменной Ь.

Руководство по actionscript. часть 1, стр. 046

Var а = new VirtualPet(«Stan»); var b = a;

В процессе выполнения первой строки приведенного выше кода средой Flash будет создан новый объект класса VirtualPet, после этого он будет записан в память и связан с локальной переменной а. В результате выполнения второй строки кода объект VirtualPet, на который уже ссылается переменная а, будет связан с локальной переменной Ь. Изменения, вносимые в объект VirtualPet через переменную а, будут естественным образом отражаться на переменной Ь, и наоборот. Например, если переменной экземпляра petName присвоить новое значение, используя код b. petName = «Tom», а затем обратиться к этой переменной с помощью конструкции a. petName, то будет получено то же значение — Тот.

Или, если переменной экземпляра petName присвоить значение, используя код а. petName = «Ken», а затем обратиться к данной переменной с помощью конструкции b. petName, будет получено то же значение — Ken.

Переменная, связанная с объектом, не содержит этот объект, а лишь ссылается на него. Сам объект хранится в системной памяти, а его сохранением занимается среда выполнения.

Переменная экземпляра для нашего животного

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

package zoo { public class VirtualZoo { private var pet;

public function VirtualZoo ( ) { this. pet = new VirtualPet(«Stan»);

}

}

}

На протяжении нескольких предыдущих разделов мы рассматривали вопросы использования переменных экземпляра для наделения объектов характеристиками класса. Теперь сосредоточим свое внимание на использовании методов экземпляра для переноса поведения класса на его объекты.

Методы экземпляра

Метод экземпляра — это отдельный набор инструкций, выполняющих определенную задачу, связанную с данным объектом. По сути, методы экземпляра описывают действия, которые может выполнять тот или иной объект. Например, в предопределенном классе Sound (экземпляры которого представляют звуки в программе) описан метод экземпляра с именем play, который позволяет начать воспроизведение звука. Аналогичным образом в предопределенном классе TextField (экземпляры которого представляют текст на экране) описан метод с именем setSelection, позволяющий изменять количество выделенных символов в текстовом поле.



Полезные ссылки
Случайные записи
  • 19.05.2010">Самоучитель по креативному веб-дизайну. Книга 2, стр.26
  • 18.05.2010">Самоучитель по креативному веб-дизайну. Книга 2, стр.87
  • 11.03.2011">Руководство по actionscript. часть 4, стр. 002
  • 24.02.2010">15 образцов типографики
  • 07.03.2011">Руководство по actionscript. часть 4, стр. 110
  • 26.02.2011">Руководство по actionscript. часть 6, стр. 058
  • 10.05.2010">Самоучитель по креативному веб-дизайну. Книга 1, стр.122
  • 17.03.2011">Руководство по actionscript. часть 2, стр. 155
  • 18.05.2010">Самоучитель по креативному веб-дизайну. Книга 2, стр.84
  • 17.06.2010">Самоучитель по креативному веб-дизайну. Книга 4, стр.9
  • 08.03.2011">Руководство по actionscript. часть 4, стр. 084
  • 20.03.2011">Руководство по actionscript. часть 2, стр. 063
  • 20.01.2013">Что включает в себя понятие «продвижение сайта»?
  • 25.05.2011">Мини-обзор нового ноутбука Sony Vaio P
  • 14.06.2010">Самоучитель по креативному веб-дизайну. Книга 4, стр.64
Опрос

Какие цвета вы предпочитаете?

View Results

Loading ... Loading ...