Интерфейсы в ActionScript 3.0 являются очень мощным средством как для полиморфизма так и для ООП и паттернов проектирования (Design Patterns) вместе взятых.
В этой статье я бы хотел рассказать о том как работают эти самые интерфейсы, что это такое и когда их выгодно использовать.
И так, интерфейс — это набор объявлений методов, который позволяет несвязанным объектам взаимодействовать друг с другом.
Структура определения интерфейса похожа на структуру определения класса за тем исключением, что интерфейс может содержать только методы без тел. Интерфейсы не могут содержать переменных или констант, но могут включать функции get и set. Для определения интерфейса используется ключевое слово interface. Например, следующий интерфейс, IExample.
Интерфейс IExample определяет протокол для сериализации объекта, то есть для преобразования объекта в формат, пригодный для хранения на устройстве или для транспортировки по сети.
public interface IExample
{
function writeExternal(input:String):void;
function readExternal():String;
}
Обратите внимание на то, что интерфейс IExample объявляется с использованием модификатора управления доступом public. Определения интерфейса могут модифицироваться только с использованием атрибутов public и internal. Объявления методов внутри определения интерфейса не могут иметь модификаторов управления доступом.
В ActionScript 3.0 используется правило именования интерфейсов с заглавной буквы I, однако в качестве имени интерфейса можно использовать любой допустимый идентификатор. Определения интерфейсов часто помещаются в верхнем уровне пакета. Определения интерфейсов нельзя помещать внутри определения класса или определения другого интерфейса.
Интерфейс может расширять один или несколько других интерфейсов. Например, следующий интерфейс IExtendExample расширяет интерфейс IExample.
public interface IExtendExample extends IExample
{
function extra():void;
}
Любой класс, внедряющий интерфейс IExtendExample, должен включать реализации не только для метода extra(), но также методы writeExternal() и readExternal(), унаследованные от интерфейса IExample.
package
{
public class CurrentExample extends Sprite implements IExtendExample
{
private var str:String;
public function CurrentExample (){}
public function writeExternal(input:String):void
{
this.str = input;
}
public function readExternal():String
{
return this.str;
}
public function extra():void{}
}
}
Давайте рассмотрим конкретный пример на реализации Паттерна ADAPTER!!!!
Первый класс Adaptee, который предоставляет нам основные функции для работы, которые в дальнейшем могут быть переписаны из класса наследника.
package
{
public class Adaptee
{
public function specificRequest( ):void
{
trace("Вызван Adaptee:specificRequest( )");
}
}
}
Реализация интерфейса...
package
{
public interface ITarget
{
function request( ):void
}
}
Наш основной класс который реализует интерфейс ITarget, обратите внимание на то что класс обязательно должен реализовать по крайнем мере одну или все функции предоставленные реализуемым интерфейсом:
package
{
public class Adapter implements ITarget
{
private var adaptee:Adaptee;
public function Adapter()
{
this.adaptee = new Adaptee();
}
public function request():void
{
adaptee.specificRequest( );
}
}
}
Ну и конечно же наш клиент, который является документ классом для приложения
package
{
import flash.display.MovieClip;
/**
* Main Class
* Документ класс для флеша
*/
public class Main extends MovieClip
{
public function Main( )
{
var target:ITarget = new Adapter( );
target.request( );
}
}
}
Клиент класс создает экземпляр класса Adapter и вызывает метод request( ) реализуемый интерфейсом ITarget. Клиент видит только функции интерфейса реализумого через Adapter класс, что дает нам хорошую гибкость в использвани объектов и их методов!
Adapter класс держит жесткий контроль доступа к существующему классу, осуществляя только интерфейс ITarget! Клиент же не должен знать о том что адаптер использует существующий класс. Так как класс Adapter создает экземпляр класса Adaptee, то между ними налаживается связь. Это не позволяет Adapter использовать подкласс Adaptee, т.е. расширять его или использовать полностью различный существующий класс, не изменяя существующий код Adaptor.
Можно было бы немного изменить класс Adapter добавив параметр в конструктор пердающий ссылку на объект Adaptee, чтобы мы могли обращаться к нему из документ класса. Хотя этот метод и не дает никаких видимых приемущест за исключеением того что можно обращаться и к экземпляру класса Adaptee... следующий пример показывает как это реализовать:
public function Adapter(a:Adaptee)
{
this.adaptee = a;
}
И в Main меняем на
public function Main( )
{
var adaptee:Adaptee = new Adaptee( );
var target:ITarget = new Adapter(adaptee);
target.request( );
}
Теперь мы можем оперировать методами и свойствами Adaptee класса из документ класса!!!))
В заключении скажу, что использование интерфейсов дает разработчикам очень гибкую структуру в построении приложений.
/* Если вы заметили в этой статье какую то не точность или вы не согласны с чем либо выше изложенным, я с удовольствием выслушаю вашу точку зрения на этот счет...Спасибо что дочитали этот пост до конца и приятного вам программирования!*/
Подписаться на:
Комментарии к сообщению (Atom)
Комментариев нет:
Отправить комментарий