Flex и RIA блоги



2022-02-26

18:31:36, Flex 2 & Co
Если у вас не запускается проект в debug mode...
Посмотрите в mm.cfg - возможно FireBug вставил туда две строки:
SuppressDebuggerExceptionDialogs=1
PreloadSWF=...
После их удаления все должно заработать.

18:31:22, Flash-разработка
Starling introduction #1
http://ifttt.com/images/no_image_card.png

Starling introduction #1



via Tumblr http://racer242.tumblr.com/post/51581507285

2015-10-05

08:03:42, Flash-ripper.com
Приходите на BAFPUG 2015 в субботу 10 октября
Приглашаем всех Flash/Flex девелоперов на встречу BAFPUG 2015. Будут доклады о разработке игр, Stage3D, архитектуре и не только. Список:
  1. Иван Шабан - Building Flexible Architecture with Robotlegs 2 - 30 мин
  2. Сергей Гончар - Fast Rendering with Starling - 30 мин
  3. Сергей Шамрук - Building Strong Architecture from Scratch - 40 мин

2015-09-09

08:48:40, Flash-ripper.com
We.GOV - як електронне самоврядування відповість на нерозв’язані проблеми України

Український та міжнародний досвід впровадження e-government показує Сергій Прокопенко у своїй презентації. Якщо ви бажаєте долучитися до розробки електронного уряду в Україні, то завітайте до тих, хто робить це прямо зараз на відкритій платформі: iGov.org.ua на GitHub.

Якщо ви хочете просто спостерігати за процесом розробки і коментувати його, то ці групи дадуть вам досить багато інформації:

Тэги: 

2015-07-23

13:52:35, Flash-ripper.com
Web Audio API: Make Some Noise! - & photo

Слайды и код к моему докладу по теории и практике веб-аудио для Kharkiv Front-End Practice. Пример ниже. Фото - еще ниже


2015-07-11

19:59:25, Flash-ripper.com
Внедрение Component Entity System в существующий проект

В своем докладе с UAFPUG-51 зависимый разработчик игр, автор loonyquack.com Андрей Саломатин показывает преимущества использования CES в играх:

Появились вопросы о Component Entity System?

Вчера, когда в твиттере объявил о том что начинаю разработку Gimmick и во время UAFPUG 51 у людей возникали вопросы по поводу CES. В этой заметке я постараюсь разобрать некоторые из них.

Андрей написал статью с ответами на вопросы, которые могут возникнуть у вас во время просмотра презентации: Component\Entity System: UI и User events:

Предыдущий доклад: Андрей Андреев: как Demo стало приложением в AppStore.


Ваш UAFPUG-51.


2015-07-07

15:23:50, Flash-ripper.com
Андрей Андреев: от Demo до AppStore

Многих волнует вопрос: как перестать беспокоиться и начать публикацию собственных приложений в App Store? Андрей Андреев из Киева дает свой ответ в небольшой презентации:

От Demo до AppStore (28 мин)

Включено обсуждение и рассказ о микротональной музыке.

Интерфейс WaveLabs

Это WaveLabs — предмет нашего изучения, приложение в AppStore, появившееся из демки для "узкого круга приближенных":

Доклад развивает "Историю одного звука" (UAFPUG-50). Там объясняются математические термины "быстрое преобразование Фурье", "Теорема Котельникова", и как начинался проект исследования звука.

Андрей — не только программист, но и математик, он открыт для интересных предложений работы по Flash или Unity, особенно наукоемких. Вот его резюме. С ним можно связаться по скайпу (SkypeID: Commovere).

Больше — на UAFPUG-51.

2015-07-01

16:26:14, Flash-ripper.com
Фото с UAFPUG-51

Update: появилось видео доклада: "От Demo к AppStore"

27 июня 2015 г. в Киеве состоялась встреча UAFPUG-51. Вот некоторые фото с нее (спасибо Андрею, Александру и Александру):

 

           

Через Фейсбук можно увидеть остальные фото с UAFPUG-51.

Видеозаписи докладов находятся на странице встречи UAFPUG-51. А доклад из доклада "Как Demo превратилось в приложение для App Store" — это доклад "История одного звука", поэтому, чтобы лучше понять новый доклад, полезно пересмотреть этот доклад-пролог.


2015-06-27

09:47:52, Flash-ripper.com
Онлайн-трансляция UAFPUG-51

Адрес трансляции:

http://adobechats.adobeconnect.com/uafpug-51/

Тэги: 

2015-06-24

12:43:22, Flash-ripper.com
UAFPUG #51 - StartDown Fest у Києві

51 зустріч групи UAFPUG відбудеться у Києві.
Час: 27 червня, з 11:00 до 17:00
Місце: офіс GlobalLogic, вул. Миколи Грінченка, 2/1.

У программі (WIP):

  1. Андрій Андрєєв: "Як моя доповідь про аналіз звуку перетворилася на аплікацію для Apple AppStore." Як робилося, та як оптимізувалося.
  2. Андрій Саломатін: "Внедрения Entity Component System в существующий игровой проект".
  3. Ростислав Сірик: ECMAScript 2015 затверджено. Що це означає — для нас та для людства.
  4. Андрій Андрєєв: "Домени пам'яті".
  5. StartDown Fest!

    Закликаємо тих, хто колись почав гру чи експеримент, але за якоїсь причини кинув це або перетворив на щось інше — продемонструвати такий проект на зустрічі.
  6. Приймаємо заявки на доповіді та виступи — пишіть!

До зустрічі!

P.S. Сторінка зустрічі UAFPUG-51 на Facebook
P.P.S. Доповіді з зустрічі UAFPUG-50


2015-06-11

12:30:38, Flash-ripper.com
Math.js

Math.js

Math.js — это математическая библиотека для JavaScript и Node.js с мощным парсером выражений, включает работу с большими и комплексными числами, матрицами, функциями и т.д. Пример можно увидеть на Mathnotepad.com или ниже:

Тэги: 

2015-05-28

14:51:40, Flash-ripper.com
Flash Online Conference №12 - уже завтра
Темы: 
  • "Video Texture on Android" – Nimisha, Chandra Prakash - Adobe
  • "ETC2(Ericsson Texture Compression) support in AIR" – Ridam Batra - Adobe
  • "iOS64 bit Support and Compilation Improvements" -  Abhinav Dandh - Adobe
  • "Standard Extended Profile" – Mayank Bhagya - Adobe
  • "Away Update" - Rob Bateman - Away3D
  • "A Preview of Feathers 2.2 and the Feathers SDK" - Josh Tynjala - Feathers
  • "BlendHX, a game engine on top of AIR capabilities." - Robert Kaveh

2015-04-15

12:21:29, Flash-ripper.com
Что вы хотите улучшить в Stage3D?

Недавно прошла организованная Сергеем Гончаром Flash Online Conference #11 (запись). А теперь Сергей обращается к сообществу с вопросом:

Мы сейчас общаемся с Adobe по поводу улучшения Stage3D и его производительности. Если у вас есть какие-то проблемы, пожалуйста напишите мне или сюда в тему.

— пишет Сергей Гончар. Ответите?

 

 

Тэги: 

2015-04-07

11:59:58, Flash-ripper.com
Сильный флэшер получит по заслугам в Днепре

Владеющий английским и ООП повелитель социалок — вооруженный паттернами, фреймворками, джейсоном, XML, AMF, Git и JIRA, будет опрошен и получит предложение работы с мед. страховкой, тренингами, молодой динамичной в Днепропетровске.

Обязанности:

  • Development client of client-server application.
  • Support and development of huge and successful project.
  • Estimating of the tasks and their successful execution in deadline.
  • Working with social networks API.
  • Creation of high-quality flexible and extendable code.

Да, это казино. Если интересно — пиши с темой "Dnepr Flash Job" на rostislav.siryk@gmail.com.

P.S. Ачивки по JS и CI дают бонус, но и без них пойдет.


2015-04-03

13:18:05, Flash-ripper.com
SomaFM HTML 5 Audio Player

Пару лет назад сделал простой онлайн-плейер для SomaFM — надоел их неудобный плейер, хочу переключать станции по одному клику, mobile browser friendly.

Исходный код: http://jsfiddle.net/varDenB/ywvjz65f/8/


2015-02-25

10:11:19, Flash-ripper.com
Создатель X Games Dev делится планами

Вадим Сиволап, автор социальной игры реального времени, то есть первой независимой украинской конференции разработчиков игр X Games Dev вышел в эфир на Robinzon.TV и рассказал о целях и задачах конференции. В частности, X Games Dev: Indie Hangout, что состоится 28 февраля в Харькове. Видео (21 мин):

До встречи в геймплее!


2015-02-13

11:43:25, Flash-ripper.com
Гики и игровые монстры собираются на XGamesDev: IndieHangout

28 февраля в Харькове состоится третья Украинская независимая конференция разработчиков игр XGamesDev. В этот раз мероприятие пройдет в формате Indie Hangout и соберет независимых разработчиков игр, которые не просто покажут гостям конференции свои творения, но и поделятся с нами опытом создания игры от идеи до ее реализации! Помимо этого, уже традиционно на конференции выступят докладчики с актуальными темами в игровой индустрии.

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

XGamesDev I - Лето'2014

XGamesDev II: IndieHangout

XGamesDev II: IndieHangout

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

Как попасть на XGamesDev: IndieHangout

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

Кип он трэк

За подробной информацией и новостями события XGamesDev: IndieHangout можно следить Вконтакте и в FacebookОфициальные группы комьюнитиВконтакте и Facebook.

Хочу посетить Хочу выступить

 

 


2015-02-12

10:26:33, Flash-ripper.com
Игровой проект по Adobe AIR на два месяца

Нужен AS3-разработчик/команда для создания игр на Adobe AIR, ориентировочно на два месяца. Назовите ваш рейт и вышлите резюме. Контакт: Наталья Веремеева.

Наталья объяснит вам суть проекта и условия сотрудничества. Если вы хотите, чтобы я рекомендовал вас, то напишите мне на rostislav.siryk@gmail.com с темой "Adobe AIR Developer".


2015-02-10

11:28:05, Flash-ripper.com
Разыгрывается билет в высшую лигу AS3-кодеров

Update: спасибо всем, кто отозвался, вам ответят на протяжении дня. Контакты пока убираем. Обратите внимание на новое предложение — игровой проект на Adobe AIR, 2 месяца.

А. М. (CryTek/Blizzard) ищет AS3-кодера, готового прямо сейчас помочь с игровым UI для ММО-игры.

  • Есть арт и готовые SWF.
  • Нужно написать AS3-код, который можно вызывать из C++.

Договариваться с A. М. ( контакты убраны в связи с высоким количеством откликов и необходимостью их качественной обработки )


2015-02-05

13:04:50, Flash-ripper.com
Урок по Adobe AIR Native Extensions для iOS, первая часть

Антон Азаров из Харькова создает серию уроков по созданию ANE для Adobe AIR под iOS. О себе он пишет: я не тот, кто одной рукой умеет писать Objective-C код, но мои старания всегда награждаются стабильной работой этих самых расширений. Итак:

Создание Adobe AIR Native Extensions для iOS. Урок 1

Создание Adobe AIR Native Extensions для iOS. Урок 1

(Тот же урок на английском: "Developing of Adobe AIR Native Extensions of iOS. Tutorial 1")

Update: ищете работу? Вам может быть интересна звездная работа для AS3-кодеров.

 


2015-02-02

13:56:02, Скачать флешки, флеш, бесплатные Flash уроки и исходники. Создание сайтов.
С# для AS3 разработчиков. Часть 5: Статические классы, Деструкторы и Приёмы для работы с конструкторами

Перевод статьи From AS3 to C#, Part 5: Static Classes, Destructors, and Constructor Tricks

В прошлый раз мы с вами рассмотрели абстрактные классы, но уже на этой неделе мы обсудим даже более абстрактный тип классов (чем абстрактные классы): статические классы. Так же, мы рассмотрим анти-конструкторы C#, которые более известны, как “деструкторы”, и, в дополнение ко всему, мы рассмотрим некоторые забавные трюки при работе с конструкторами классов.

 

Статические классы

Давайте начнём сегодняшнюю статью с “даже более абстрактных” классов: статических классов. Работая с абстрактными классами, вы всё ещё можете расширять их и создавать экземпляры дочерних классов:

abstract class Shape
{
}
 
class Square : Shape // legal
{
}
 
new Shape(); // illegal
new Square(); // legal

Работая со статическими классами, вы не можете ни инстанциировать, ни наследовать их. Вы никогда не сможете создать экземпляр подобного класса:

static class Shape
{
}
 
class Square : Shape // illegal
{
}
 
new Shape(); // illegal
new Square(); // illegal

Но для чего вообще могут понадобиться подобные классы? Подобные классы могут быть хорошим местом для хранения статических функций, полей и свойств. И, так как вы не можете создавать экземпляры подобных классов, в них запрещено использование не статических полей любых типов данных. Конструкторы экземпляров класса так же запрещены, т.к. класс автоматически приравнивается к sealed классам. Довольно популярный пример использования подобных классов – класс Math. Вам вряд ли когда-либо нужно будет создать экземпляр этого класса, но внутри него содержится большое количество полезных статических функций (например Abs) и полей (например PI). Вот, как может выглядеть реализация подобного класса:

public static class Math
{
    // remember that 'const' is automatically static
    // also, this would surely have more precision
    public const double PI = 3.1415926;
 
    public static double Abs(double value)
    {
        return value >= 0 ? value : -value;
    }
}
 
new Math(); // illegal

В AS3 по-умолчанию нет поддержки статических классов на этапе компиляции, но вы можете обойти это ограничение, используя проверки на этапе проигрывания (run-time). Всё, что вам нужно будет сделать – это объявить класс, как final, и всегда бросать ошибку в конструкторе этого класса:

public final class Math
{
    public static const PI:Number = 3.1415926;
 
    public function Math()
    {
        throw new Error("Math is static");
    }    
 
    public static function abs(value:Number): Number
    {
        return value >= 0 ? value : -value;
    }
}
 
new Math(); // legal, but throws an exception

 

Деструкторы

Следующим пунктом в сегодняшней программе идут деструкторы, которые являются “анти-конструкторами”, потому что они отвечают за уничтожение класса, а не за его создание, как в случае с обычными конструкторами. Деструкторы вызываются сборщиками мусора (Garbage Collector) непосредственно перед тем, как объект освобождает занимаемую им память. Вот, как они выглядят:

class TemporaryFile
{
    ~TemporaryFile()
    {
        // cleanup code goes here
    }
}

Для создания деструктора, достаточно добавить ~ к имени класса. Деструктор может быть только один, и с ним нельзя использовать модификаторы доступа. Обычно, необходимости в создании деструкторов нет, но в некоторых случаях они могут быть полезными, в качестве способа очистки ресурсов после использования класса. В примере ниже деструктор используется для удаления из операционной системы временного файла, который в другом случае не будет удалён, т.к. GC никогда не сделает этого:

using System.IO;
 
class TemporaryFile
{
    public String Path { get; private set; }
 
    TemporaryFile(String path)
    {
        Path = path;
        File.Create(path);
    }
 
    ~TemporaryFile()
    {
        File.Delete(Path);
    }
}
 
// Create the temporary file
TemporaryFile temp = new TemporaryFile("/path/to/temp/file");
 
// ... use the temporary file
 
// Remove the last reference to the TemporaryFile instance
// GC will now collect temp, call the destructor, and delete the file
temp = null;

 

В данном примере класс TemporaryFile создаёт файл в конструкторе экземпляра класса, и удаляет файл, когда на экземпляр класса нет ссылок и класс готов быть собранным GC, чтобы освободить память. В AS3 нет функций, которые бы вызывались, когда экземпляр класса готов быть собранным GC. Обычно, чтобы реализовать подобное поведение, необходимо вручную создавать и вызывать “псевдо-деструкторы” (обычно их называют dispose или destroy):

import flash.filesystem;
 
class TemporaryFile
{
    private var _path:String;
    public function get path(): String { return _path; }
    public function set path(p:String): void { _path = p; }
 
    private var _file:File;
 
    function TemporaryFile(path:String)
    {
        _path = path;
        _file = new File(path);
        var stream:FileStream = new FileStream();
        stream.open(_file, FileMode.WRITE);
    }
 
    function dispose(): void
    {
        _file.deleteFile();
    }
}
 
// Create the temporary file
var temp:TemporaryFile = new TemporaryFile("/path/to/temp/file");
 
// ... use the temporary file
 
// Manually call dispose() to delete the temporary file
temp.dispose();
 
// Remove the last reference to the TemporaryFile instance
// GC will now collect temp
temp = null;

 

Трюки при работе с конструкторами

Последней темой на сегодня будут трюки при работе с конструкторами. Мы уже разбирали способ вызова конструктора базового класса, используя ключевое слово base (аналогично использованию ключевого слова super в AS3):

class Polygon
{
    Polygon(int numSides)
    {
    }
}
class Triangle : Polygon
{
    Triangle()
        : base(3) // call the Polygon constructor
    {
    }
}

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

class Vector3
{
    double X;
    double Y;
    double Z;
 
    Vector3()
    {
        X = 0;
        Y = 0;
        Z = 0;
    }
 
    Vector3(double x, double y, double z)
    {
        X = x;
        Y = y;
        Z = z;
    }
 
    Vector3(Vector3 vec)
    {
        X = vec.X;
        Y = vec.Y;
        Z = vec.Z;
    }
}
 
Vector3 v1 = new Vector3();        // (0, 0, 0)
Vector3 v2 = new Vector3(1, 2, 3); // (1, 2, 3)
Vector3 v3 = new Vector3(v2);      // (1, 2, 3)

 

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

class Vector3
{
    double X;
    double Y;
    double Z;
 
    Vector3()
        : this(0, 0, 0)
    {
    }
 
    Vector3(double x, double y, double z)
    {
        X = x;
        Y = y;
        Z = z;
    }
 
    Vector3(Vector3 vec)
        : this(vec.X, vec.Y, vec.Z)
    {
    }
}
 
Vector3 v1 = new Vector3();        // (0, 0, 0)
Vector3 v2 = new Vector3(1, 2, 3); // (1, 2, 3)
Vector3 v3 = new Vector3(v2);      // (1, 2, 3)

Мы можем использовать this() для вызова других конструкторов в рамках нашего класса (по аналогии с base(), что позволяло вызывать конструктор родительского класса). И снова, в AS3 не было подобного функционала по-умолчанию, поэтому его приходилось “эмулировать” с помощью статических псевдо-конструкторов, которые вызывали функции наподобие init/setup/contruct у создаваемых объектов:

class Vector3
{
    var x:Number;
    var y:Number;
    var z:Number;
 
    function Vector3()
    {
        init(0, 0, 0);
    }
 
    // pseudo-constructor
    static function fromComponents(x:Number, y:Number, z:Number)
    {
        var ret:Vector3 = new Vector3();
        ret.init(x, y, z);
        return ret;
    }
 
    // pseudo-constructor    
    static function fromVector(Vector3 vec)
    {
        var ret:Vector3 = new Vector3();
        ret.init(vec.X, vec.Y, vec.Z);
        return ret;
    }
 
    // helper function
    function init(x:Number, y:Number, z:Number): void
    {
        this.x = x;
        this.y = y;
        this.z = z;
    }
}
 
var v1:Vector3 = new Vector3();                   // (0, 0, 0)
var v2:Vector3 = Vector3.fromComponents(1, 2, 3); // (1, 2, 3)
var v3:Vector3 = Vector3.fromVector(v2);          // (1, 2, 3)

На этом мы сегодня закончим и, как обычно, в завершении статьи мы сравним описанные сегодня особенности работы с C# и AS3:

////////
// C# //
////////
 
// Static class
public static class MathHelpers
{
	public const double DegreesToRadians = Math.PI / 180.0;
	public const double RadiansToDegrees = 180.0 / Math.PI;
 
 
 
 
 
 
	public static double ConvertDegreesToRadians(double degrees)
	{
		return degrees * DegreesToRadians;
	}
 
	public static double ConvertRadiansToDegrees(double radians)
	{
		return radians * RadiansToDegrees;
	}
}
 
// Class with a destructor
class TemporaryFile
{
	public String Path { get; private set; }
 
 
 
 
 
 
 
 
 
 
 
	TemporaryFile(String path)
	{
		Path = path;
		File.Create(path);
	}
 
 
 
	// Destructor
	~TemporaryFile()
	{
		File.Delete(Path);
	}
}
 
// Class with shared constructor code
class Vector3
{
	double X;
	double Y;
	double Z;
 
	Vector3()
		: this(0, 0, 0)
	{
	}
 
	// shared constructor code
	Vector3(double x, double y, double z)
	{
		X = x;
		Y = y;
		Z = z;
	}
 
	Vector3(Vector3 vec)
		: this(vec.X, vec.Y, vec.Z)
	{
	}
 
 
 
 
 
 
 
 
 
 
}
/////////
// AS3 //
/////////
 
// Static class - runtime only
public class MathHelpers
{
    public static const DegreesToRadians:Number = Math.PI / 180.0;
    public static const RadiansToDegrees:Number = 180.0 / Math.PI;
 
    public function MathHelpers()
    {
        throw new Error("MathHelpers is static");
    }
 
    public static function ConvertDegreesToRadians(degrees:Number): Number
    {
        return degrees * DegreesToRadians;
    }
 
    public static function ConvertRadiansToDegrees(radians:Number): Number
    {
        return radians * RadiansToDegrees;
    }
}
 
// Class with a destructor
class TemporaryFile
{
    private var _path:String;
    public function get path(): String
    {
        return _path;
    }
    public function set path(p:String): void
    {
        _path = p;
    }
 
    private var _file:File;
 
    function TemporaryFile(path:String)
    {
        _path = path;
        _file = new File(path);
        var stream:FileStream = new FileStream();
        stream.open(_file, FileMode.WRITE);
    }
 
    // Destructor - must be called manually
    function dispose(): void
    {
        _file.deleteFile();
    }
}
 
// Class with shared constructor code
class Vector3
{
    var x:Number;
    var y:Number;
    var z:Number;
 
    function Vector3()
    {
        init(0, 0, 0);
    }
 
 
    static function fromComponents(x:Number, y:Number, z:Number)
    {
        var ret:Vector3 = new Vector3();
        ret.init(x, y, z);
            return ret;
    }
 
    static function fromVector(Vector3 vec)
    {
        var ret:Vector3 = new Vector3();
        ret.init(vec.X, vec.Y, vec.Z);
            return ret;
    }
 
    // shared constructor code - helper function required
    function init(x:Number, y:Number, z:Number): void
    {
        this.x = x;
        this.y = y;
        this.z = z;
    }
}

В следующей статье мы разберём новые особенности C#, которых не было в AS3!

Запись С# для AS3 разработчиков. Часть 5: Статические классы, Деструкторы и Приёмы для работы с конструкторами впервые появилась Flashist.


13:56:02, Скачать флешки, флеш, бесплатные Flash уроки и исходники. Создание сайтов.
С# для AS3 разработчиков. Часть 5: Статические классы, Деструкторы и Приёмы для работы с конструкторами

Перевод статьи From AS3 to C#, Part 5: Static Classes, Destructors, and Constructor Tricks

В прошлый раз мы с вами рассмотрели абстрактные классы, но уже на этой неделе мы обсудим даже более абстрактный тип классов (чем абстрактные классы): статические классы. Так же, мы рассмотрим анти-конструкторы C#, которые более известны, как “деструкторы”, и, в дополнение ко всему, мы рассмотрим некоторые забавные трюки при работе с конструкторами классов.

 

Статические классы

Давайте начнём сегодняшнюю статью с “даже более абстрактных” классов: статических классов. Работая с абстрактными классами, вы всё ещё можете расширять их и создавать экземпляры дочерних классов:

abstract class Shape
{
}
 
class Square : Shape // legal
{
}
 
new Shape(); // illegal
new Square(); // legal

Работая со статическими классами, вы не можете ни инстанциировать, ни наследовать их. Вы никогда не сможете создать экземпляр подобного класса:

static class Shape
{
}
 
class Square : Shape // illegal
{
}
 
new Shape(); // illegal
new Square(); // illegal

Но для чего вообще могут понадобиться подобные классы? Подобные классы могут быть хорошим местом для хранения статических функций, полей и свойств. И, так как вы не можете создавать экземпляры подобных классов, в них запрещено использование не статических полей любых типов данных. Конструкторы экземпляров класса так же запрещены, т.к. класс автоматически приравнивается к sealed классам. Довольно популярный пример использования подобных классов – класс Math. Вам вряд ли когда-либо нужно будет создать экземпляр этого класса, но внутри него содержится большое количество полезных статических функций (например Abs) и полей (например PI). Вот, как может выглядеть реализация подобного класса:

public static class Math
{
    // remember that 'const' is automatically static
    // also, this would surely have more precision
    public const double PI = 3.1415926;
 
    public static double Abs(double value)
    {
        return value >= 0 ? value : -value;
    }
}
 
new Math(); // illegal

В AS3 по-умолчанию нет поддержки статических классов на этапе компиляции, но вы можете обойти это ограничение, используя проверки на этапе проигрывания (run-time). Всё, что вам нужно будет сделать – это объявить класс, как final, и всегда бросать ошибку в конструкторе этого класса:

public final class Math
{
    public static const PI:Number = 3.1415926;
 
    public function Math()
    {
        throw new Error("Math is static");
    }    
 
    public static function abs(value:Number): Number
    {
        return value >= 0 ? value : -value;
    }
}
 
new Math(); // legal, but throws an exception

 

Деструкторы

Следующим пунктом в сегодняшней программе идут деструкторы, которые являются “анти-конструкторами”, потому что они отвечают за уничтожение класса, а не за его создание, как в случае с обычными конструкторами. Деструкторы вызываются сборщиками мусора (Garbage Collector) непосредственно перед тем, как объект освобождает занимаемую им память. Вот, как они выглядят:

class TemporaryFile
{
    ~TemporaryFile()
    {
        // cleanup code goes here
    }
}

Для создания деструктора, достаточно добавить ~ к имени класса. Деструктор может быть только один, и с ним нельзя использовать модификаторы доступа. Обычно, необходимости в создании деструкторов нет, но в некоторых случаях они могут быть полезными, в качестве способа очистки ресурсов после использования класса. В примере ниже деструктор используется для удаления из операционной системы временного файла, который в другом случае не будет удалён, т.к. GC никогда не сделает этого:

using System.IO;
 
class TemporaryFile
{
    public String Path { get; private set; }
 
    TemporaryFile(String path)
    {
        Path = path;
        File.Create(path);
    }
 
    ~TemporaryFile()
    {
        File.Delete(Path);
    }
}
 
// Create the temporary file
TemporaryFile temp = new TemporaryFile("/path/to/temp/file");
 
// ... use the temporary file
 
// Remove the last reference to the TemporaryFile instance
// GC will now collect temp, call the destructor, and delete the file
temp = null;

 

В данном примере класс TemporaryFile создаёт файл в конструкторе экземпляра класса, и удаляет файл, когда на экземпляр класса нет ссылок и класс готов быть собранным GC, чтобы освободить память. В AS3 нет функций, которые бы вызывались, когда экземпляр класса готов быть собранным GC. Обычно, чтобы реализовать подобное поведение, необходимо вручную создавать и вызывать “псевдо-деструкторы” (обычно их называют dispose или destroy):

import flash.filesystem;
 
class TemporaryFile
{
    private var _path:String;
    public function get path(): String { return _path; }
    public function set path(p:String): void { _path = p; }
 
    private var _file:File;
 
    function TemporaryFile(path:String)
    {
        _path = path;
        _file = new File(path);
        var stream:FileStream = new FileStream();
        stream.open(_file, FileMode.WRITE);
    }
 
    function dispose(): void
    {
        _file.deleteFile();
    }
}
 
// Create the temporary file
var temp:TemporaryFile = new TemporaryFile("/path/to/temp/file");
 
// ... use the temporary file
 
// Manually call dispose() to delete the temporary file
temp.dispose();
 
// Remove the last reference to the TemporaryFile instance
// GC will now collect temp
temp = null;

 

Трюки при работе с конструкторами

Последней темой на сегодня будут трюки при работе с конструкторами. Мы уже разбирали способ вызова конструктора базового класса, используя ключевое слово base (аналогично использованию ключевого слова super в AS3):

class Polygon
{
    Polygon(int numSides)
    {
    }
}
class Triangle : Polygon
{
    Triangle()
        : base(3) // call the Polygon constructor
    {
    }
}

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

class Vector3
{
    double X;
    double Y;
    double Z;
 
    Vector3()
    {
        X = 0;
        Y = 0;
        Z = 0;
    }
 
    Vector3(double x, double y, double z)
    {
        X = x;
        Y = y;
        Z = z;
    }
 
    Vector3(Vector3 vec)
    {
        X = vec.X;
        Y = vec.Y;
        Z = vec.Z;
    }
}
 
Vector3 v1 = new Vector3();        // (0, 0, 0)
Vector3 v2 = new Vector3(1, 2, 3); // (1, 2, 3)
Vector3 v3 = new Vector3(v2);      // (1, 2, 3)

 

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

class Vector3
{
    double X;
    double Y;
    double Z;
 
    Vector3()
        : this(0, 0, 0)
    {
    }
 
    Vector3(double x, double y, double z)
    {
        X = x;
        Y = y;
        Z = z;
    }
 
    Vector3(Vector3 vec)
        : this(vec.X, vec.Y, vec.Z)
    {
    }
}
 
Vector3 v1 = new Vector3();        // (0, 0, 0)
Vector3 v2 = new Vector3(1, 2, 3); // (1, 2, 3)
Vector3 v3 = new Vector3(v2);      // (1, 2, 3)

Мы можем использовать this() для вызова других конструкторов в рамках нашего класса (по аналогии с base(), что позволяло вызывать конструктор родительского класса). И снова, в AS3 не было подобного функционала по-умолчанию, поэтому его приходилось “эмулировать” с помощью статических псевдо-конструкторов, которые вызывали функции наподобие init/setup/contruct у создаваемых объектов:

class Vector3
{
    var x:Number;
    var y:Number;
    var z:Number;
 
    function Vector3()
    {
        init(0, 0, 0);
    }
 
    // pseudo-constructor
    static function fromComponents(x:Number, y:Number, z:Number)
    {
        var ret:Vector3 = new Vector3();
        ret.init(x, y, z);
        return ret;
    }
 
    // pseudo-constructor    
    static function fromVector(Vector3 vec)
    {
        var ret:Vector3 = new Vector3();
        ret.init(vec.X, vec.Y, vec.Z);
        return ret;
    }
 
    // helper function
    function init(x:Number, y:Number, z:Number): void
    {
        this.x = x;
        this.y = y;
        this.z = z;
    }
}
 
var v1:Vector3 = new Vector3();                   // (0, 0, 0)
var v2:Vector3 = Vector3.fromComponents(1, 2, 3); // (1, 2, 3)
var v3:Vector3 = Vector3.fromVector(v2);          // (1, 2, 3)

На этом мы сегодня закончим и, как обычно, в завершении статьи мы сравним описанные сегодня особенности работы с C# и AS3:

////////
// C# //
////////
 
// Static class
public static class MathHelpers
{
	public const double DegreesToRadians = Math.PI / 180.0;
	public const double RadiansToDegrees = 180.0 / Math.PI;
 
 
 
 
 
 
	public static double ConvertDegreesToRadians(double degrees)
	{
		return degrees * DegreesToRadians;
	}
 
	public static double ConvertRadiansToDegrees(double radians)
	{
		return radians * RadiansToDegrees;
	}
}
 
// Class with a destructor
class TemporaryFile
{
	public String Path { get; private set; }
 
 
 
 
 
 
 
 
 
 
 
	TemporaryFile(String path)
	{
		Path = path;
		File.Create(path);
	}
 
 
 
	// Destructor
	~TemporaryFile()
	{
		File.Delete(Path);
	}
}
 
// Class with shared constructor code
class Vector3
{
	double X;
	double Y;
	double Z;
 
	Vector3()
		: this(0, 0, 0)
	{
	}
 
	// shared constructor code
	Vector3(double x, double y, double z)
	{
		X = x;
		Y = y;
		Z = z;
	}
 
	Vector3(Vector3 vec)
		: this(vec.X, vec.Y, vec.Z)
	{
	}
 
 
 
 
 
 
 
 
 
 
}
/////////
// AS3 //
/////////
 
// Static class - runtime only
public class MathHelpers
{
    public static const DegreesToRadians:Number = Math.PI / 180.0;
    public static const RadiansToDegrees:Number = 180.0 / Math.PI;
 
    public function MathHelpers()
    {
        throw new Error("MathHelpers is static");
    }
 
    public static function ConvertDegreesToRadians(degrees:Number): Number
    {
        return degrees * DegreesToRadians;
    }
 
    public static function ConvertRadiansToDegrees(radians:Number): Number
    {
        return radians * RadiansToDegrees;
    }
}
 
// Class with a destructor
class TemporaryFile
{
    private var _path:String;
    public function get path(): String
    {
        return _path;
    }
    public function set path(p:String): void
    {
        _path = p;
    }
 
    private var _file:File;
 
    function TemporaryFile(path:String)
    {
        _path = path;
        _file = new File(path);
        var stream:FileStream = new FileStream();
        stream.open(_file, FileMode.WRITE);
    }
 
    // Destructor - must be called manually
    function dispose(): void
    {
        _file.deleteFile();
    }
}
 
// Class with shared constructor code
class Vector3
{
    var x:Number;
    var y:Number;
    var z:Number;
 
    function Vector3()
    {
        init(0, 0, 0);
    }
 
 
    static function fromComponents(x:Number, y:Number, z:Number)
    {
        var ret:Vector3 = new Vector3();
        ret.init(x, y, z);
            return ret;
    }
 
    static function fromVector(Vector3 vec)
    {
        var ret:Vector3 = new Vector3();
        ret.init(vec.X, vec.Y, vec.Z);
            return ret;
    }
 
    // shared constructor code - helper function required
    function init(x:Number, y:Number, z:Number): void
    {
        this.x = x;
        this.y = y;
        this.z = z;
    }
}

В следующей статье мы разберём новые особенности C#, которых не было в AS3!

Запись С# для AS3 разработчиков. Часть 5: Статические классы, Деструкторы и Приёмы для работы с конструкторами впервые появилась Flashist.


2015-01-27

13:35:16, Скачать флешки, флеш, бесплатные Flash уроки и исходники. Создание сайтов.
С# для AS3 разработчиков. Часть 4: Абстрактные классы и функции

Перевод статьи From AS3 to C#, Part 4: Abstract Classes and Functions

В этой статье мы наконец-то начнём разбираться в нюансах C#, аналогов которых нет в AS3. И первым делом мы рассмотрим абстрактные классы и функции. В AS3 необходимо было придумывать обходные пути, чтобы они работали правильно на этапе исполнения (run-time). Но C# предоставляет возможность заставить их работать на этапе компиляции (compile-time), и сегодня мы разберём эти способы.

 

Статические инициализаторы

Но, до этого, я бы хотел рассказать об одной особенности AS3 классов, о которой я забыл рассказать в предыдущих статьях: статические инициализаторы (static initializers), так же известные как инициализаторы класса, конструкторы класса или статические конструкторы. Это – функция, которая будет вызвана автоматически, когда статические поля класса должны быть инициализированы. Вот, как это выглядело в AS3:

class Person
{
    private static var NEXT_ID:int;
    private var id:int;
 
    // static initializer:
    {
        NEXT_ID = 1;
    }
 
    // instance constructor
    function Person()
    {
        id = NEXT_ID++;
    }
}

Статические инициализаторы используются не часто, т.к. у нас есть возможность объявлять и инициализировать поля в одно и то же время. Например:

private static var NEXT_ID:int = 1;

Но, они могут быть полезны, если необходимо реализовать более сложную логику поведения приложения. В любом случае, вот, как это может быть реализовано в C#:

class Person
{
    private static int NextID;
    private int id;
 
    // static initializer:
    static Person()
    {
        NextID = 1;
    }
 
    // instance constructor
    Person()
    {
        id = NextID++;
    }
}

Статические инициализаторы в C# называются “статическими конструкторами” и работают по аналогии с обычными конструкторами, но не для отдельных экземпляров классов, а для всего класса целиком. Синтаксис подобных конструкторов совпадает с обычными, но в начале объявления конструктора добавляется ключевое слово static. У данных конструкторов не может быть модификаторов доступа (private, public и т.п.) и они не могут принимать входящие параметры.

 

Абстрактные классы

А теперь, давайте поговорим об абстрактных классах: это – такие классы, которые не могут быть инстанциированы напрямую. Чтобы создать экземпляр абстрактного класса, вам необходимо будет создать не абстрактный класс, который будет наследоваться от абстрактного, и инстанциировать этот не абстрактный класс. По-умолчанию в AS3 нет подобного функционала на этапе компиляции, но, существует довольно популярный способ обойти это ограничение:

class ExtrudedShape
{
    private var depth:int;
 
    protected static const HIDDEN_KEY:Object = {};
 
    function ExtrudedShape(ABSTRACT:Object, depth:int)
    {
        if (ABSTRACT != HIDDEN_KEY)
        {
            throw new ArgumentError("ExtrudedShape is an abstract class");
        }
 
        this.depth = depth;
    }
 
    function get area(): int
    {
        return 0;
    }
 
    function get volume(): int
    {
        return depth * area;
    }
}

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

var shape:ExtrudedShape = new ExtrudedShape(null, 3);

Но на этапе исполнения сработает проверка первого аргумента, что повлечёт за собой появление ошибки ArgumentError, и экземпляр ExtrudedShape не будет создан. Это произойдёт из-за того, что классы, не унаследованные от ExtrudedShape не будут иметь доступа к protected константе HIDDEN_KEY, но, в то же время, классы-производные от ExtrudedShape смогут обращаться к этой переменной для передачи в родительский конструктор:

class ExtrudedCircle extends ExtrudedShape
{
    function ExtrudedCircle(depth:int)
    {
        super(HIDDEN_KEY, depth);
    }
}

Это – довольно эффективный способ реализации абстрактных классов на этапе проигрывания, но C# предоставляет возможность сделать всю работу на этапе компиляции:

abstract class ExtrudedShape
{
    private int depth { get; private set; }
 
    ExtrudedShape(int depth)
    {
        this.depth = depth;
    }
 
    int Area
    {
        get { return 0; }
    }
 
    int Volume
    {
        get { return depth * Area; }
    }
}

Обратите внимание на использование ключевого слова abstract вначале класса. Оно означает, что компилятор не должен разрешать создание данного класса напрямую. Данный подход не требует дополнительного кода или “обходных путей”, которые необходимы в AS3 (производным классам не нужно использовать HIDDEN_KEY, а их инициализация и объявление выглядит точно так же, как и у других классов):

class ExtrudedCircle : ExtrudedShape
{
    ExtrudedCircle(int depth)
        : base(depth)
    {
    }
}

 

Абстрактные функции

Абстрактные функции используются в тех случаях, когда необходимо указать, что реализация определённой функции, обязательно должна быть переопределена в дочернем классе. И снова, в AS3 нет возможности реализовать подобное на этапе компиляции, но, как и в случае с абстрактными классами, существует способ обойти это ограничение:

class ExtrudedShape
{
    private var depth:int;
 
    protected static const HIDDEN_KEY:Object = {};
 
    function ExtrudedShape(ABSTRACT:Object, depth:int)
    {
        if (ABSTRACT != HIDDEN_KEY)
        {
            throw new ArgumentError("ExtrudedShape is an abstract class");
        }
 
        this.depth = depth;
    }
 
    function get area(): int
    {
        throw new Error("'get area' is an abstract function");
        return 0;
    }
 
    function get volume(): int
    {
        return depth * area;
    }
}

В данном примере класс ExtrudedShape не реализует функционал функции get area, так как он ничего не знает о ней. В данной версии, обращение к функции get area класса ExtrudedShape вызовет ошибку. Данный подход позволяет реализовать абстрактные функции на этапе воспроизведения, но не на этапе компиляции. Например, следующий код будет успешно компилироваться без реализации функции get area:

class ExtrudedCircle extends ExtrudedShape
{
}

Вместо этого, в C# мы можем просто использовать ключевое слово abstract:

abstract class ExtrudedShape
{
    private int depth { get; private set; }
 
    ExtrudedShape(int depth)
    {
        this.depth = depth;
    }
 
    abstract public int Area
    {
        get;
    }
 
    int Volume
    {
        get { return depth * Area; }
    }
}
class ExtrudedCircle : ExtrudedShape
{
    private int area;
 
    override int Area
    {
        get { return area; }
    }
}

Это же ключевое слово будет использоваться для обычных функций (не геттер/сеттер):

abstract class GameEntity
{
    abstract void TakeDamage(int damage);
}
 
class Enemy : GameEntity
{
    int health;
 
    override void TakeDamage(int damage)
    {
        health -= damage;
    }
}

Сегодня мы обсудили абстрактные классы и функции, а так же статические инициализаторы. Для закрепления, давайте сравним особенности реализации этого функционала в C# и AS3:

////////
// C# //
////////
 
// Abstract class
abstract class GameEntity
{
    private static int NextID;
 
 
 
    protected int health;
 
    int id;
 
    static GameEntity()
    {
        NextID = 1;
    }
 
    GameEntity(int health)
    {
 
 
 
 
 
        this.health = health;
        this.id = NextID++;
    }
 
    // Abstract property
    bool Friendly
    {
 
        abstract get;
    }
 
    // Abstract function
    abstract void TakeDamage(int amount)
    {
 
    }
}
 
// Non-abstract ("concrete") class
class Enemy : GameEntity
{
    Enemy(int health)
        : base(health)
    {
    }
 
    // Implemented abstract property
    override bool Friendly
    {
        get { return false; }
    }
 
    // Implemented abstract function
    override void TakeDamage(int amount)
    {
        health -= amount;
    }
}
/////////
// AS3 //
/////////
 
// Abstract class - only enforced at run-time
class GameEntity
{
    private static var NEXT_ID:int;
 
    protected static const HIDDEN_KEY:Object = {};
 
    protected var health:int;
 
    var id:int;
 
    // Static initializer
    {
        NEXT_ID = 1;
    }
 
    function GameEntity(ABSTRACT:Object, health:int)
    {
        if (ABSTRACT != HIDDEN_KEY)
        {
            throw new ArgumentError("GameEntity is abstract");
        }
 
        this.health = health;
        this.id = NEXT_ID++;
    }
 
    // Abstract property/getter - only enforced at run-time
    function get friendly(): Boolean
    {
        throw new Error("'get friendly' is abstract");
        return false;
    }
 
    // Abstract function - only enforced at run-time
    function takeDamage(amount:int): void
    {
        throw new Error("takeDamage is abstract");
    }
}
 
// Non-abstract ("concrete") class
class Enemy extends GameEntity
{
    function Enemy(health:int)
    {
        super(HIDDEN_KEY, health);
    }
 
    // Implemented abstract property
    override function get friendly(): Boolean
    {
        return false;
    }
 
    // Implemented abstract function
    override function takeDamage(amount:int): void
    {
        health -= amount;
    }
}

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

Оставайтесь с нами!

 

Запись С# для AS3 разработчиков. Часть 4: Абстрактные классы и функции впервые появилась Flashist.


13:35:16, Скачать флешки, флеш, бесплатные Flash уроки и исходники. Создание сайтов.
С# для AS3 разработчиков. Часть 4: Абстрактные классы и функции

Перевод статьи From AS3 to C#, Part 4: Abstract Classes and Functions

В этой статье мы наконец-то начнём разбираться в нюансах C#, аналогов которых нет в AS3. И первым делом мы рассмотрим абстрактные классы и функции. В AS3 необходимо было придумывать обходные пути, чтобы они работали правильно на этапе исполнения (run-time). Но C# предоставляет возможность заставить их работать на этапе компиляции (compile-time), и сегодня мы разберём эти способы.

 

Статические инициализаторы

Но, до этого, я бы хотел рассказать об одной особенности AS3 классов, о которой я забыл рассказать в предыдущих статьях: статические инициализаторы (static initializers), так же известные как инициализаторы класса, конструкторы класса или статические конструкторы. Это – функция, которая будет вызвана автоматически, когда статические поля класса должны быть инициализированы. Вот, как это выглядело в AS3:

class Person
{
    private static var NEXT_ID:int;
    private var id:int;
 
    // static initializer:
    {
        NEXT_ID = 1;
    }
 
    // instance constructor
    function Person()
    {
        id = NEXT_ID++;
    }
}

Статические инициализаторы используются не часто, т.к. у нас есть возможность объявлять и инициализировать поля в одно и то же время. Например:

private static var NEXT_ID:int = 1;

Но, они могут быть полезны, если необходимо реализовать более сложную логику поведения приложения. В любом случае, вот, как это может быть реализовано в C#:

class Person
{
    private static int NextID;
    private int id;
 
    // static initializer:
    static Person()
    {
        NextID = 1;
    }
 
    // instance constructor
    Person()
    {
        id = NextID++;
    }
}

Статические инициализаторы в C# называются “статическими конструкторами” и работают по аналогии с обычными конструкторами, но не для отдельных экземпляров классов, а для всего класса целиком. Синтаксис подобных конструкторов совпадает с обычными, но в начале объявления конструктора добавляется ключевое слово static. У данных конструкторов не может быть модификаторов доступа (private, public и т.п.) и они не могут принимать входящие параметры.

 

Абстрактные классы

А теперь, давайте поговорим об абстрактных классах: это – такие классы, которые не могут быть инстанциированы напрямую. Чтобы создать экземпляр абстрактного класса, вам необходимо будет создать не абстрактный класс, который будет наследоваться от абстрактного, и инстанциировать этот не абстрактный класс. По-умолчанию в AS3 нет подобного функционала на этапе компиляции, но, существует довольно популярный способ обойти это ограничение:

class ExtrudedShape
{
    private var depth:int;
 
    protected static const HIDDEN_KEY:Object = {};
 
    function ExtrudedShape(ABSTRACT:Object, depth:int)
    {
        if (ABSTRACT != HIDDEN_KEY)
        {
            throw new ArgumentError("ExtrudedShape is an abstract class");
        }
 
        this.depth = depth;
    }
 
    function get area(): int
    {
        return 0;
    }
 
    function get volume(): int
    {
        return depth * area;
    }
}

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

var shape:ExtrudedShape = new ExtrudedShape(null, 3);

Но на этапе исполнения сработает проверка первого аргумента, что повлечёт за собой появление ошибки ArgumentError, и экземпляр ExtrudedShape не будет создан. Это произойдёт из-за того, что классы, не унаследованные от ExtrudedShape не будут иметь доступа к protected константе HIDDEN_KEY, но, в то же время, классы-производные от ExtrudedShape смогут обращаться к этой переменной для передачи в родительский конструктор:

class ExtrudedCircle extends ExtrudedShape
{
    function ExtrudedCircle(depth:int)
    {
        super(HIDDEN_KEY, depth);
    }
}

Это – довольно эффективный способ реализации абстрактных классов на этапе проигрывания, но C# предоставляет возможность сделать всю работу на этапе компиляции:

abstract class ExtrudedShape
{
    private int depth { get; private set; }
 
    ExtrudedShape(int depth)
    {
        this.depth = depth;
    }
 
    int Area
    {
        get { return 0; }
    }
 
    int Volume
    {
        get { return depth * Area; }
    }
}

Обратите внимание на использование ключевого слова abstract вначале класса. Оно означает, что компилятор не должен разрешать создание данного класса напрямую. Данный подход не требует дополнительного кода или “обходных путей”, которые необходимы в AS3 (производным классам не нужно использовать HIDDEN_KEY, а их инициализация и объявление выглядит точно так же, как и у других классов):

class ExtrudedCircle : ExtrudedShape
{
    ExtrudedCircle(int depth)
        : base(depth)
    {
    }
}

 

Абстрактные функции

Абстрактные функции используются в тех случаях, когда необходимо указать, что реализация определённой функции, обязательно должна быть переопределена в дочернем классе. И снова, в AS3 нет возможности реализовать подобное на этапе компиляции, но, как и в случае с абстрактными классами, существует способ обойти это ограничение:

class ExtrudedShape
{
    private var depth:int;
 
    protected static const HIDDEN_KEY:Object = {};
 
    function ExtrudedShape(ABSTRACT:Object, depth:int)
    {
        if (ABSTRACT != HIDDEN_KEY)
        {
            throw new ArgumentError("ExtrudedShape is an abstract class");
        }
 
        this.depth = depth;
    }
 
    function get area(): int
    {
        throw new Error("'get area' is an abstract function");
        return 0;
    }
 
    function get volume(): int
    {
        return depth * area;
    }
}

В данном примере класс ExtrudedShape не реализует функционал функции get area, так как он ничего не знает о ней. В данной версии, обращение к функции get area класса ExtrudedShape вызовет ошибку. Данный подход позволяет реализовать абстрактные функции на этапе воспроизведения, но не на этапе компиляции. Например, следующий код будет успешно компилироваться без реализации функции get area:

class ExtrudedCircle extends ExtrudedShape
{
}

Вместо этого, в C# мы можем просто использовать ключевое слово abstract:

abstract class ExtrudedShape
{
    private int depth { get; private set; }
 
    ExtrudedShape(int depth)
    {
        this.depth = depth;
    }
 
    abstract public int Area
    {
        get;
    }
 
    int Volume
    {
        get { return depth * Area; }
    }
}
class ExtrudedCircle : ExtrudedShape
{
    private int area;
 
    override int Area
    {
        get { return area; }
    }
}

Это же ключевое слово будет использоваться для обычных функций (не геттер/сеттер):

abstract class GameEntity
{
    abstract void TakeDamage(int damage);
}
 
class Enemy : GameEntity
{
    int health;
 
    override void TakeDamage(int damage)
    {
        health -= damage;
    }
}

Сегодня мы обсудили абстрактные классы и функции, а так же статические инициализаторы. Для закрепления, давайте сравним особенности реализации этого функционала в C# и AS3:

////////
// C# //
////////
 
// Abstract class
abstract class GameEntity
{
    private static int NextID;
 
 
 
    protected int health;
 
    int id;
 
    static GameEntity()
    {
        NextID = 1;
    }
 
    GameEntity(int health)
    {
 
 
 
 
 
        this.health = health;
        this.id = NextID++;
    }
 
    // Abstract property
    bool Friendly
    {
 
        abstract get;
    }
 
    // Abstract function
    abstract void TakeDamage(int amount)
    {
 
    }
}
 
// Non-abstract ("concrete") class
class Enemy : GameEntity
{
    Enemy(int health)
        : base(health)
    {
    }
 
    // Implemented abstract property
    override bool Friendly
    {
        get { return false; }
    }
 
    // Implemented abstract function
    override void TakeDamage(int amount)
    {
        health -= amount;
    }
}
/////////
// AS3 //
/////////
 
// Abstract class - only enforced at run-time
class GameEntity
{
    private static var NEXT_ID:int;
 
    protected static const HIDDEN_KEY:Object = {};
 
    protected var health:int;
 
    var id:int;
 
    // Static initializer
    {
        NEXT_ID = 1;
    }
 
    function GameEntity(ABSTRACT:Object, health:int)
    {
        if (ABSTRACT != HIDDEN_KEY)
        {
            throw new ArgumentError("GameEntity is abstract");
        }
 
        this.health = health;
        this.id = NEXT_ID++;
    }
 
    // Abstract property/getter - only enforced at run-time
    function get friendly(): Boolean
    {
        throw new Error("'get friendly' is abstract");
        return false;
    }
 
    // Abstract function - only enforced at run-time
    function takeDamage(amount:int): void
    {
        throw new Error("takeDamage is abstract");
    }
}
 
// Non-abstract ("concrete") class
class Enemy extends GameEntity
{
    function Enemy(health:int)
    {
        super(HIDDEN_KEY, health);
    }
 
    // Implemented abstract property
    override function get friendly(): Boolean
    {
        return false;
    }
 
    // Implemented abstract function
    override function takeDamage(amount:int): void
    {
        health -= amount;
    }
}

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

Оставайтесь с нами!

 

Запись С# для AS3 разработчиков. Часть 4: Абстрактные классы и функции впервые появилась Flashist.


2015-01-26

07:29:27, Скачать флешки, флеш, бесплатные Flash уроки и исходники. Создание сайтов.
С# для AS3 разработчиков. Часть 3: get, set, sealed, using, const, readonly

 

Перевод статьи From AS3 to C#, Part 3: AS3 Class Parity

Сегодня мы закончим разбираться с классами в C# (с точки зрения AS3 разработчика) и подготовимся к следующей статье, в которой мы сможем познакомиться с понятиями, аналогов которых нет в AS3. В текущей статье мы рассмотрим способ реализации:
- геттеров/сеттеров (getter/setter)
- функций и классов, которые нельзя переопределять/наследовать (final)
- констант
- пакетов

 

Get/Set функции

Давайте начнём с геттеров и сеттеров. Чтобы освежить память, вот, как они выглядели в AS3:

class Person
{
    private var _name:String;
    public function get name(): String
    {
        return _name;
    }
    public function set name(n:String): void
    {
        _name = n;
    }
}

А вот, эквивалент в С#:

class Person
{
    private String _name;
    public String Name
    {
        get
        {
            return _name;
        }
        set
        {
            _name = value;
        }
    }
}

Как мы можем увидеть, в C#, вместо объявления 2 функций, геттер и сеттер объявлены в виде единственной переменной. Правда, эта переменная не заканчивается точкой с запятой (;), а содержит блок в виде фигурных скобок, внутри которого есть 2 части: get{} и set{}. Эти части являются геттер и сеттер функциями. Внутри сеттера у вас будет доступ к новому ключевому слову value, оно представляет собой значение, которое должно быть установлено и вам не нужно объявлять его, как это приходилось делать в AS3. Если не брать в расчёт это отличие в синтаксисе, геттеры и сеттеры работают одинаково в C# и AS3.

C# предоставляет возможность использовать сокращённую запись для подобных функций, позволяя избежать написание лишнего кода для простых функций:

class Person
{
    public String Name { get; set; }
}

Использование этой конструкции автоматически создаст переменную _name и геттер/сеттер функции, как в примере выше. Но что, если вам не нужна функция-сеттер? Просто уберите её:

class Person
{
    public String Name { get; }
}

Скорее всего, вам необходимо будет, как минимум, предоставить возможность классу Person устанавливать значения этой переменной. Для этого сеттер может быть объявлен private:

class Person
{
    public String Name { get; private set; }
}

И ещё, немного терминологии C#: поля класса, у которых есть get и/или set функции (Name), называются “свойства”. Переменные, которые используются для хранения этих данных (_name), называются “вспомогательные поля”.

 

Final/sealed функции

А теперь, давайте поговорим о final функциях, которые не могут быть переопределены (AS3):

class Person
{
    final function print(): void
    {
        trace("I'm a Person");
    }
}
 
class MyPerson extends Person
{
    // illegal
    override function print(): void
    {
        trace("I'm not just a Person, I'm a MyPerson too");
    }
}

С# предоставляет идентичный функционал, используя слово sealed:

class Person
{
    sealed void Print()
    {
        Debug.Log("I'm a Person");
    }
}
 
class MyPerson extends Person
{
    // illegal
    override void Print()
    {
        Debug.Log("I'm not just a Person, I'm a MyPerson too");
    }
}

 

Пакеты и namespace

Пакеты в AS3:

package com.jacksondunstan.examples
{
    class Person
    {
    }
}

В C#, пакеты называются namespace, вот и всё:

namespace com.jacksondunstan.examples
{
    class Person
    {
    }
}

Чтобы получить доступ к пакету внутри .as файла, вы можете импортировать пакет:

import com.jacksondunstan.examples;
 
class Printer
{
    function print(person:Person): void
    {
        trace("person has name: " + person.name);
    }
}

В C# вы используете ключевое слово using для namespace:

using com.jacksondunstan.examples;
 
class Printer
{
    void Print(Person person)
    {
        Debug.Log("person has name: " + person.name);
    }
}

 

Константы и readonly переменные

И напоследок, давайте поговорим о константах. Вот, как в AS3 может быть создано поле, которое нельзя изменить после объявления:

class Person
{
    private static const MIN_TEEN_AGE:int = 13;
    private static const MAX_TEEN_AGE:int = 19;
    var age:int;
 
    function IsTeen(): Boolean
    {
        return age >= MIN_TEEN_AGE && age <= MAX_TEEN_AGE;
    }
}

Вот, как это можно сделать в C#:

class Person
{
    private const int MinTeenAge = 13;
    private const int MaxTeenAge = 19;
    int Age;
 
    bool IsTeen()
    {
        return Age >= MinTeenAge && Age <= MaxTeenAge;
    }
}

Важный нюанс: в C# для констант можно использовать только базовые типы (например, int) и строки. Это необходимо потому, что подобное поле не будет существовать на самом деле, вместо этого, везде, где оно используется, будут подставлены значения этого поля. Так же, это означает, что подобные поля автоматически становятся статическими (static), и их не нужно объявлять, как static отдельно. После компиляции класс Person в C# будет выглядеть следующим образом:

class Person
{
    int Age;
 
    bool IsTeen()
    {
        return Age >= 13 && Age <= 19;
    }
}

В AS3 ключевое слово const использовалось исключительно для проверки на этапе компиляции и не приводило к изменениям/подстановкам в коде. Если необходимо добиться похожего поведения в C# или необходимо использовать не базовый тип данных (например, Person), то нужно использовать ключевое слово readonly:

class Person
{
    static readonly Person Newborn = new Person(0);
    readonly int Age;
 
    Person(int age)
    {
        Age = age;
    }
}

В примере выше присутствует 2 readonly поля:

1) Newborn – поле, которое было объявлено с ключевым словом static (readonly поля, в отличии от констант, не обязательно являются static). Данное поле будет инициализировано в том месте, где оно объявлено (по-аналогии с константами в AS3).

2) Age – поле, которое является readonly, но не является static. Оно будет инициализировано в конструкторе.

 

В завершении, сравнение описанных особенностей C# и AS3 кода:

////////
// C# //
////////
 
// Collection of classes being used by this file
using org.apache.coolstuff;
 
// Collection of classes
namespace com.jacksondunstan.examples
{
    class Person
    {
        // Complex getters and setters
        private String _name;
        String Name
        {
            get
            {
                return _name;
            }
            set
            {
                _name = value;
            }
        }
 
        // Simple getters and setters
        int Age { get; set; }
 
        // Read-only field
        readonly int ID;
 
        // Inlined field
        const int AdultAge = 18;
 
        // Function that can't be overridden
        sealed void Print()
        {
            Debug.Log("Name: " + name + ", ID: " + ID);
        }
    }
}
/////////
// AS3 //
/////////
 
// Collection of classes being used by this file
import org.apache.coolstuff;
 
// Collection of classes
package com.jacksondunstan.examples
{
    class Person
    {
        // Complex getters and setters
        private var _name:String;
        function get name(): String
        {
            return _name;
        }
        function set name(value:String): void
        {
            _name = value;
        }
 
 
 
 
        // Simple getters and setters
        // {not supported. use complex instead.}
 
        // Read-only field
        const var ID:int;
 
        // Inlined field
        // {not supported. use compile-time constants via command-line instead.}
 
        // Function that can't be overridden
        final function print(): void
        {
            trace("Name: " + name + ", ID: " + ID);
        }
    }
}

В следующей статье мы, наконец-то, начнём рассматривать понятия, аналогов которых нет в AS3.

Не переключайте канал!

 

Запись С# для AS3 разработчиков. Часть 3: get, set, sealed, using, const, readonly впервые появилась Flashist.


07:29:27, Скачать флешки, флеш, бесплатные Flash уроки и исходники. Создание сайтов.
С# для AS3 разработчиков. Часть 3: get, set, sealed, using, const, readonly

 

Перевод статьи From AS3 to C#, Part 3: AS3 Class Parity

Сегодня мы закончим разбираться с классами в C# (с точки зрения AS3 разработчика) и подготовимся к следующей статье, в которой мы сможем познакомиться с понятиями, аналогов которых нет в AS3. В текущей статье мы рассмотрим способ реализации:
– геттеров/сеттеров (getter/setter)
– функций и классов, которые нельзя переопределять/наследовать (final)
– констант
– пакетов

 

Get/Set функции

Давайте начнём с геттеров и сеттеров. Чтобы освежить память, вот, как они выглядели в AS3:

class Person
{
    private var _name:String;
    public function get name(): String
    {
        return _name;
    }
    public function set name(n:String): void
    {
        _name = n;
    }
}

А вот, эквивалент в С#:

class Person
{
    private String _name;
    public String Name
    {
        get
        {
            return _name;
        }
        set
        {
            _name = value;
        }
    }
}

Как мы можем увидеть, в C#, вместо объявления 2 функций, геттер и сеттер объявлены в виде единственной переменной. Правда, эта переменная не заканчивается точкой с запятой (;), а содержит блок в виде фигурных скобок, внутри которого есть 2 части: get{} и set{}. Эти части являются геттер и сеттер функциями. Внутри сеттера у вас будет доступ к новому ключевому слову value, оно представляет собой значение, которое должно быть установлено и вам не нужно объявлять его, как это приходилось делать в AS3. Если не брать в расчёт это отличие в синтаксисе, геттеры и сеттеры работают одинаково в C# и AS3.

C# предоставляет возможность использовать сокращённую запись для подобных функций, позволяя избежать написание лишнего кода для простых функций:

class Person
{
    public String Name { get; set; }
}

Использование этой конструкции автоматически создаст переменную _name и геттер/сеттер функции, как в примере выше. Но что, если вам не нужна функция-сеттер? Просто уберите её:

class Person
{
    public String Name { get; }
}

Скорее всего, вам необходимо будет, как минимум, предоставить возможность классу Person устанавливать значения этой переменной. Для этого сеттер может быть объявлен private:

class Person
{
    public String Name { get; private set; }
}

И ещё, немного терминологии C#: поля класса, у которых есть get и/или set функции (Name), называются “свойства”. Переменные, которые используются для хранения этих данных (_name), называются “вспомогательные поля”.

 

Final/sealed функции

А теперь, давайте поговорим о final функциях, которые не могут быть переопределены (AS3):

class Person
{
    final function print(): void
    {
        trace("I'm a Person");
    }
}
 
class MyPerson extends Person
{
    // illegal
    override function print(): void
    {
        trace("I'm not just a Person, I'm a MyPerson too");
    }
}

С# предоставляет идентичный функционал, используя слово sealed:

class Person
{
    sealed void Print()
    {
        Debug.Log("I'm a Person");
    }
}
 
class MyPerson extends Person
{
    // illegal
    override void Print()
    {
        Debug.Log("I'm not just a Person, I'm a MyPerson too");
    }
}

 

Пакеты и namespace

Пакеты в AS3:

package com.jacksondunstan.examples
{
    class Person
    {
    }
}

В C#, пакеты называются namespace, вот и всё:

namespace com.jacksondunstan.examples
{
    class Person
    {
    }
}

Чтобы получить доступ к пакету внутри .as файла, вы можете импортировать пакет:

import com.jacksondunstan.examples;
 
class Printer
{
    function print(person:Person): void
    {
        trace("person has name: " + person.name);
    }
}

В C# вы используете ключевое слово using для namespace:

using com.jacksondunstan.examples;
 
class Printer
{
    void Print(Person person)
    {
        Debug.Log("person has name: " + person.name);
    }
}

 

Константы и readonly переменные

И напоследок, давайте поговорим о константах. Вот, как в AS3 может быть создано поле, которое нельзя изменить после объявления:

class Person
{
    private static const MIN_TEEN_AGE:int = 13;
    private static const MAX_TEEN_AGE:int = 19;
    var age:int;
 
    function IsTeen(): Boolean
    {
        return age >= MIN_TEEN_AGE && age <= MAX_TEEN_AGE;
    }
}

Вот, как это можно сделать в C#:

class Person
{
    private const int MinTeenAge = 13;
    private const int MaxTeenAge = 19;
    int Age;
 
    bool IsTeen()
    {
        return Age >= MinTeenAge && Age <= MaxTeenAge;
    }
}

Важный нюанс: в C# для констант можно использовать только базовые типы (например, int) и строки. Это необходимо потому, что подобное поле не будет существовать на самом деле, вместо этого, везде, где оно используется, будут подставлены значения этого поля. Так же, это означает, что подобные поля автоматически становятся статическими (static), и их не нужно объявлять, как static отдельно. После компиляции класс Person в C# будет выглядеть следующим образом:

class Person
{
    int Age;
 
    bool IsTeen()
    {
        return Age >= 13 && Age <= 19;
    }
}

В AS3 ключевое слово const использовалось исключительно для проверки на этапе компиляции и не приводило к изменениям/подстановкам в коде. Если необходимо добиться похожего поведения в C# или необходимо использовать не базовый тип данных (например, Person), то нужно использовать ключевое слово readonly:

class Person
{
    static readonly Person Newborn = new Person(0);
    readonly int Age;
 
    Person(int age)
    {
        Age = age;
    }
}

В примере выше присутствует 2 readonly поля:

1) Newborn – поле, которое было объявлено с ключевым словом static (readonly поля, в отличии от констант, не обязательно являются static). Данное поле будет инициализировано в том месте, где оно объявлено (по-аналогии с константами в AS3).

2) Age – поле, которое является readonly, но не является static. Оно будет инициализировано в конструкторе.

 

В завершении, сравнение описанных особенностей C# и AS3 кода:

////////
// C# //
////////
 
// Collection of classes being used by this file
using org.apache.coolstuff;
 
// Collection of classes
namespace com.jacksondunstan.examples
{
    class Person
    {
        // Complex getters and setters
        private String _name;
        String Name
        {
            get
            {
                return _name;
            }
            set
            {
                _name = value;
            }
        }
 
        // Simple getters and setters
        int Age { get; set; }
 
        // Read-only field
        readonly int ID;
 
        // Inlined field
        const int AdultAge = 18;
 
        // Function that can't be overridden
        sealed void Print()
        {
            Debug.Log("Name: " + name + ", ID: " + ID);
        }
    }
}
/////////
// AS3 //
/////////
 
// Collection of classes being used by this file
import org.apache.coolstuff;
 
// Collection of classes
package com.jacksondunstan.examples
{
    class Person
    {
        // Complex getters and setters
        private var _name:String;
        function get name(): String
        {
            return _name;
        }
        function set name(value:String): void
        {
            _name = value;
        }
 
 
 
 
        // Simple getters and setters
        // {not supported. use complex instead.}
 
        // Read-only field
        const var ID:int;
 
        // Inlined field
        // {not supported. use compile-time constants via command-line instead.}
 
        // Function that can't be overridden
        final function print(): void
        {
            trace("Name: " + name + ", ID: " + ID);
        }
    }
}

В следующей статье мы, наконец-то, начнём рассматривать понятия, аналогов которых нет в AS3.

Не переключайте канал!

 

Запись С# для AS3 разработчиков. Часть 3: get, set, sealed, using, const, readonly впервые появилась Flashist.


2015-01-19

12:49:50, Flash-ripper.com
Дмитрий Пилипенко: первый опыт разработки Swift-приложения для iOS

Cчастливые обладатели iPhone с iOS8 - если вы устали от частых вводов email вручную, то знайте: появилось приложение, где это делается в одно нажатие — OftenType.

Это первое приложение на Swift от Дмитрия П. Своим опытом он делится на Medium-е: OftenType


2015-01-14

15:31:25, Flash-ripper.com
Теория всего, океан и алгебра

Гарретт Лиси - физик и серфер, разработал восьмимерную теорию всего, построенную на алгебре Ли E8. В своем докладе на TED он рассказывает об этом за 15 минут (а в конце - о том, как ему удается быть физиком-серфером). Также популярно объясняет важность бозона Хиггса и его место в теории.

Видео "Теории Всего" с субтитрами (на русском):

Текстовая версия видео:

0:18Йоу, чувак! Зацени эти улетные уравнения! Шикарно! В течение следующих восемнадцати минут я сделаю все возможное, чтобы описать красоту квантовой механики вообще без уравнений. Мы можем узнать много нового, изучая кораллы. Коралл — очень красивое и необычное животное; каждый риф состоит из тысяч отдельных полипов. Полипы постоянно почкуются и ответвляются, в результате у них образуются генетически идентичные соседи. Представим себе, что кораллы умеют мыслить, и мы можем поговорить с каждым полипом. Мы бы спросили одного из них, как он оказался на определенном месте относительно своих соседей — был ли это слепой случай, судьба, или что-то еще?

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

1:32В отличие от нас, гипотетический разумный коралл очень хорошо подготовлен к осознанию принципов квантовой механики. Математические принципы квантовой механики крайне точно описывают, как работает наша вселенная. Согласно этим принципам, наша действительность постоянно ветвится на различные её варианты, как коралл. Человеку очень сложно понять этот процесс, поскольку мы наблюдаем только один вариант действительности. Впервые странность квантового мира была описана Эрвином Шрёдингером и его кошкой. Кошке больше нравится эта версия. (Смех в зале) В этой модели Шрёдингер находится в ящике с радиоактивной пробой. Согласно законам квантовой механики она одновременно находится в состоянии, в котором она излучает и в состоянии, в котором она не излучает. (Смех в зале) Если проба излучает, то коробка заполняется ядовитым газом и Шрёдингер умирает. В другой ветви реальности ученый остается живым. Каждая из ветвей воспринимается участниками независимо, и они считают, что другой ветви не существует.

2:33Нам кажется это странным, поскольку каждый из нас воспринимает лишь одну из реальностей, а других ее ветвей мы не видим. Как будто каждый из нас, подобно Шрёдингеру, похож на коралл и ветвится на разные варианты реальности.Математические основы квантовой механики показывают, что в микромасштабах наш мир устроен именно так. Можно обобщить все это в одно утверждение: всё, что может произойти, происходит. Вот так работает квантовая механика. Но это не означает, что может произойти вообще все, что угодно. Остальная физика занимается описанием того, что может произойти, и того, что не может. Физикам известно, что любой процесс можно свести к геометрическим построениям и взаимодействию элементарных частиц. Любые процессы могут произойти только если это взаимодействие идеально отлажено.

3:16А теперь я хотел бы рассказать о том, что мы знаем про эти частицы — что они из себя представляют и как сбалансированы. Внутри этой машины пучок протонов и антипротонов ускоряется до скорости, близкой к скорости света. Затем два пучка сталкиваются, что приводит к выбросу энергии. Энергия мгновенно преобразуется в поток субатомных частиц, а специальные датчики и компьютеры затем вычисляют их свойства. Длина контура этого огромного устройства, большого адронного коллайдера, построенного в CERN, в Женеве, составляет двадцать семь километров, а рабочая мощность в пять раз выше, чем у всего Монтерея.Мы не можем точно предсказать,какие именно частицы возникнут в результате каждого столкновения. И хотя принципы квантовой механики утверждают, что всё возможно, физики указывают набор реализуемых частиц. У них должно быть столько же энергии и такая же масса, как у протона и антипротона. Любые частицы, лежащие за этим энергетическим лимитом, не реализуются, и мы не способны их увидеть. Новый ускоритель частиц чрезвычайно интересен,поскольку он увеличит энергетический лимит в семь раз относительно существующего, так что очень скоро мы узнаем о новых частицах.

4:23Однако перед тем как рассказать вам о том, что нам предстоит узнать, я опишу уже известные нам частицы. Тут целый зоопарк субатомных частиц. Каждый знаком с электронами, и многие люди в этом зале зарабатывают неплохие деньги, гоняя их туда-сюда. (Смех в зале) Но у электрона есть нейтральная пара под названием нейтрино — с очень маленькой массой и без заряда. У u- и d-кварков, наоборот, очень большие массы. Они объединяются в тройки и создают протоны и нейтроны внутри атомов. Все эти частицы бывают правовинтовыми и левовинтовыми; у них также есть античастицы с противоположными зарядами.Знакомые нам частицы порождают менее знакомые вторые и третьи поколения, с теми же зарядами, но б


2015-01-12

14:52:22, Flash-ripper.com
Работа в Киеве - Mobile Developer/Team Lead для Avid

В офис GlobalLogic в Киеве требуется опытный разработчик мобильных приложений под Android/iOS, клиент Avid. Детали:


Avid is a global leader in technology solutions for film, video, audio, animation, games and broadcast industry: the shows, commercials and news programs you watch on TV, the entertaining video and film stories you see on the web and on the big screen, the personal audio and video treasures that people make at home to preserve their favorite moments in life.
Our products — and our customers — have received the most prestigious awards in the industries that we serve, including multiple Oscar, Emmy and Grammy statuettes.
Avid in partnership with GlobalLogic is running a Product Engineering Lab in Ukraine.

We are looking for an experienced leader with a passion for cutting edge technology to lead the design and development of Android and iPhone apps using Agile/Scrum processes. A successful candidate will be familiar with and actively involved in current mobile technology developments. The ideal candidate will act both as an architect, as well as, a strong individual contributor and technical expert right from concept stage until delivery and post launch support.

Our team consists of talented people who are passionate about their work. We offer a casual, fast-paced, collaborative environment that stimulates ideas and innovation. You will find comfortable place packed with features and happy people, friendly and professional. Paid vacations and seek leaves, medical insurance and performance bonus program are included.


JOB DESCRIPTION

  • JOB RESPONSIBILITIES

    A successful candidate will be able to lead the development of mobile (Android/iOS) client (phone/tablet) solutions that provides news journalists with continuous remote access to features which allow them to view, edit, and create news stories remotely.

    Candidate will participate in development using a SCRUM process as scrum team member. Working with product owner, scrum team will receive stories for each sprint, estimate them, choose for implementation and successfully deliver within sprint timeframe removing impediments.

  • REQUIRED

    • 3+ years of experience in software development and a strong command of object oriented principles/programming
    • Demonstrated strengths in Java and the Android SDK
    • Demonstrated strengths in Objective-C and the iOS platform
    • Experience in continuous integration and continuous delivery
    • Experience with automation and unit tests (i.e. JUnit)
    • Passion for coding standards and best practices as well as writing elegant code
    • Understanding of web/REST services and how to use them in mobile development
    • A proven track record to work independently, though collaboratively, willingness to learn, self-motivated and productive
    • Fluency in English (both spoken and written) and the ability to communicate efficiently in English via both phone and e-mail is a must

  • PREFERED

    • iPhone / Android SDK expertise
    • Understanding of Agile/Scrum processes, experience in working with agile tools — JIRA or similar
    • TDD, Jenkins, UI automation

Интересует работа? Присылайте резюме на rostislav.siryk@gmail.com


2014-12-22

06:44:57, Flash-ripper.com
1 февраля 2015 года и App Store

С 1 февраля 2015 года AppStore обещает прекратить принимать приложения с 32-битной архитектурой. А вот что сегодня обнаружилось при попытке собрать приложение с ANE-расширением, собранным на маке с последним 16м бета FLEX + AIR SDK:

Warning: Apple App Store doesn't allow 32-bit applications any more. To include 64-bit support in your application, please use a Mac machine. 64-bit packaging is presently not supported on Windows.

Надеюсь, скоро сделают поддержку и на Windows.


| Следующие 30