Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Понять интерфейсы (http://www.flasher.ru/forum/showthread.php?t=145702)

TanaTiX 17.10.2010 00:52

Понять интерфейсы
 
В очередной раз возвращаюсь к этой теме и пытаюсь найти плюсы для себя, как человека, в единственном лице работающим над к.-л. проектом.сКажите пожалуйста, есть ли смысл? Если есть - какие плюсы? Мое понимание ситуации на данный момент сводится лишь к тому что мне более чем достаточно будет наследование (extends), а интерфесы (interface) - лишние куски кода, которые в моем случае не нужны (т.к. над проектом работаю один).

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

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

В общем надеюсь на помощь. Интересует как часто? когда? в каких ситуациях? какие при этом я получаю преимущества? (не зависимо от количества разработчиков:) ) В общем буду благодарен за любые советы и мысли на тему интерфейсов. Спасибо.
====================
Upd. еще раз спасибо всем откликнувшимся. Думаю у меня еще будет повод отписаться :)

alatar 17.10.2010 01:01

Представьте ситуацию, у вас есть n-е количество классов у которых нет общего предка, но у всех есть некий набор одинаковых методов и их надо обрабатывать. Тут уже просто наследованием не обойтись. Логичнее описать методы в интерфейсе и работать с объектами как с интерфейсом. Примеры IItemRenderer, IDataRenderer.

MrPoma 17.10.2010 01:09

Использование или неиспользование интерфейсных классов это всего лишь проектировочный ход.

http://ru.wikipedia.org/wiki/Обращение_контроля

Чтобы разобраться в этом вопросе, рекомендую прочитать книжек, например, "Рефакторинг" (Мартин Фаулер).

chabapok 17.10.2010 01:32

у многих языков нету множественного наследования классов, а множественное наследование интерфейсов - есть. Поэтому это просто иногда удобно.
Что касается флеша -- интерфейсы можно выбросить, а типизацию переменных убрать, и все будет работать, но иногда удобней их иметь. Это -- раз.

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

три -- при помощи is можно проверять принадлежность переменной интерфейсу.
типа

if (clicketObj is ITransparentButton)clicketObj.alpha =1
if (clicketObj is IToolTip) clicketObj.showToolTip("Ахтунг!")

Часто так делать удобней, чем заводить внутри класса соответствующие флажки.

Bgg 17.10.2010 01:37

Цитата:

Сообщение от TanaTiX (Сообщение 943206)
В очередной раз возвращаюсь к этой теме и пытаюсь найти плюсы для себя, как человека, в единственном лице работающим над к.-л. проектом.сКажите пожалуйста, есть ли смысл? Если есть - какие плюсы? Мое понимание ситуации на данный момент сводится лишь к тому что мне более чем достаточно будет наследование (extends), а интерфесы (interface) - лишние куски кода, которые в моем случае не нужны (т.к. над проектом работаю один).

Если вы понимаете смысл интерфейсов, то зачем искать плюсы там, где для вас на данный момент их ещё нет? Это как с MVC, не всем нужно, но много кто знает и хотят его использовать.

Wolsh 17.10.2010 02:35

То, о чем говорит chabapok в пункте 3 - называется еще Маркерами, или маркерными интерфейсами. Они могут вообще ничего не содержать == не требовать от классов реализации каких-то методов. Их смысл - просто дать понять другим классам, что с этими можно что-то делать (пример - IBitmapDrawable, который имплементят все ДисплейОбжекты). Допустим у Вас 15 наследников Спрайта, и Вы хотите разрешить только 4 из них растягивать по горизонтали, а остальные - нет. Помечаете четыре маркером - implements IHScalable, и перед попыткой растянуть такой спрайт спрашиваете, можно ли? Можно конечно завести булево свойство, но - незадача - Вам придется заводить его во всех 15-и классах, и во всех иметь это странное непрактичное свойство, к тому же вылезающее при автокомплите. Хороший пример - тот самый IBitmapDrawable. Представьте, что адобовцам пришлось бы во все(!) классы добавлять такой флаг - может или нет экземпляр быть отрисован в битмап. А тут просто пометили маркером один супер-класс и вуаля.

TanaTiX 17.10.2010 03:13

alatar, как я понимаю в приведенном примере как раз наследование подходит лучше
MrPoma, спасибо за ссылку, читаю про SOLID.
chabapok
Цитата:

у многих языков нету множественного наследования классов, а множественное наследование интерфейсов - есть. Поэтому это просто иногда удобно.
Это удобно что? Как по мне множественное наследование классов было бы гораздо продуктивней при разработке. Или я не прав?
Цитата:

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

три --...
Т.е. следующий пример будет верен:
У нас есть массив(корзинка) продуктов: фрукты и овощи. Они могу быть красными, желтыми и зелеными. И мы вместо того чтоб заводить переменные, как подсказывает Wolsh, просто проверяем интерфесы, при этом можем сделать выборку как только овощей, так и красных овощей.
BggЯ как раз думаю, что не понимаю смысл интерфейсов, потому и создал тему.
Wolsh
Цитата:

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

Вам придется заводить его во всех 15-и классах
но ведь мне по аналогии придется во все 15 классов дописывать конструкцию типа "implements IClass". А вотношении суперкласса я также могу воспользоваться наследованием.

Из того что понял на данный момент:
- полезно при первичном проектировании
- использование интерфейсов вместо булевых переменных

expl 17.10.2010 03:26

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

Пример, где наследование не справляется:
Например есть менеджер подсказок и ему нужно передать объект с полем hintText
(безобразное решение для огранизации подсказок, но сейчас не об этом)
надо показать подсказку и над классом, унаследованным от SimpleButton и над классом, унаследованным от Sprite, здесь мы не сможем впихнуть функцию:
Код AS3:

public function get hintText()

в цепочку наследования
придется реализовывать этот метод и в MySimpleButton и в MySprite, а чтобы с ними обоими мог работать менеджер (без дурацких проверок на тип и опасного приведения типов) пусть реализуют интерфейс IHintTextable

В этом плане очень сильно недостает интерфейса IDisplayObject (хорошо хоть IEventDispatcher сделали), т.е. сейчас у нас есть в проекте 2 gui библиотеки
и есть 2 типа кнопок.
Одни наследуются от Sprite, другие - от SimpleButton
У обоих кнопок единтсвенное значимое отличие от DisplayObject - наличие свойства "enabled"
Ну и всё - приплыли. Использовать одни и теже классы работающие с 2-мя кнопками нельзя (вернее можно, но криво) - получается либо:
Код AS3:

var button:IMyButton = ...
addChild(button as DisplayObject)

либо:
Код AS3:

var button:DisplayObject = ...
manager.addButton(button as IMyButton);

А все потому, что нельзя написать, нет интерфейса:
Код AS3:

interface IMyButton extends IDisplayObject

Вот так НЕиспользование интерфейсов ухудшает гибкость на примере API флешплеера

Wolsh 17.10.2010 04:22

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

но ведь мне по аналогии придется во все 15 классов дописывать конструкцию типа "implements IClass".
Вы не поняли. В том то и дело, что Вам надо будет только пометить 4 класса, что они "могут расширяться по горизонтали", а с остальными 11 делать ничего не нужно. Точно также как два адобовских класса имплементят IBitmapDrawable и только их (и их наследников) можно передавать в BitmapData::draw(). Все остальные классы вовсе не помечены каким-нибудь IDontBitmapDrawable. Их "НЕ" содержится в том что они НЕ реализуют IBitmapDrawable. Вот если бы Вы заводили поле - то да, у всех 15-ти, иначе как спросить?)) Через hasOwnProperty? Куда уж кривее - заводить поле, чтобы спрашивать не его значение, а - есть ли само поле))).
Основная задача интерфейсов, кроме собственно гарантии наличия методов - объединение того, что не может наследоваться от одного предка, как в случае с DisplayObject и BitmapData. В нередких случаях, когда есть какой-то контейнер (пакер), в который могут добавляться РАЗНЫЕ объекты (виджеты), имеющие интерфейс - т.е. методы - для работы в этом контейнере, Интерфейсы незаменимы. Многоуровневое меню, где пунктом может быть как кнопка, так и другое меню; статусБар - эта панелька внизу многих приложений, в которой помещается несколько Информеров - координаты мыши, подсказка к инструменту, индикатор прогресса, иконки дополнительных служб. Вы стали бы писать отдельный класс, чтобы все это унаследовать от него? А если таких интерфейсов понадобится пять - создавать цепочку из пяти суперклассов? Прелесть Интерфейсов в том что один Класс может реализовывать их несколько сразу, плюс наследовать.

gloomyBrain 17.10.2010 05:38

Пожалуй, стоит добавить, что при загрузке логики извне (т.е. swf-файла с классами) интерфейсы могут быть полезны. Допустим, имеем игру с 4 режимами. И каждый режим лежит в отдельном swf-файле. Как, спрашивается, управлять этими режимами из главной swf-ки (контейнера)? Ответ - использовать интерфейсы. С их помощью можно сохранить типизацию при работе с, в общем, неизвестным содержимым.

alatar 17.10.2010 09:13

Цитата:

как я понимаю в приведенном примере как раз наследование подходит лучше
Видимо недостаточно ясно выразился. В приведенном примере не может быть использовано наследование. Например интерфейс IClone может быть реализован как в визуальном, так и в не визуальном классе. В случае ItemRenderer, IDataRenderer, компонент не может заранее знать, от какого предка будет наследоваться визуализатор.

TanaTiX 17.10.2010 14:08

Ответов много, и они объемные, за что отдельное спасибо, поэтому буду отвечать постепенно (к тому же если никто не ответит - они автоматом в конец дописываются)

expl
Цитата:

пусть реализуют интерфейс IHintTextable
Т.е. в классах MySimpleButton и MySprite я прописываю "immplements IHintTextable", но ведь и затем мне все равно придется написать в каждом классе все функции, объявленные в интерфейсе? Т.е. получается опять защита от склероза:(
Цитата:

А все потому, что нельзя написать, нет интерфейса:
А вот допустим мы написали таким образом и у нас есть IDisplayObject, как тогда дальше?
По поводу тех 2х примеров с интерфейсами (не совсем понимаю их работу):
1) мы создаем переменную, которая по сути является интерфейсом. Мы разве можем добавить на сцену интерфейс, даже с учетом приведения типов? Что вообще получится в результате? Мне почему-то казалось, что мы не можем добавить интерфейс на сцену, а если и можем, то какой в этом смысл, ведь там ничего кроме списка объявленных методов с атрибутами и переменных ничего нет.
2) Тут получается мы сразу добавляем интерфейс, т.е. к нему приводим и все это в каком-то контейнере? Это какой-то хитрый контейнер или это может быть любой спрайт?
Такое впечатление, что мне еще рано вникать в нюансы с IDisplayObject, т.к. пока еще с основами не разобрался.

Добавлено через 13 минут
Wolsh
Цитата:

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

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

Wolsh 17.10.2010 15:43

Цитата:

а можно примерчик глянуть?
Вы как между строк читаете.. Я же привел Вам реальный пример - IBitmapDrawable. Его имплементят только два класса - BitmapData и DisplayObject (соответственно все его наследники).
У класса BitmapData есть метод draw(), который принимает как параметр - внимание - не DisplayObject, а именно интерфейс IBitmapDrawable, т.е. И битмапдату И дисплейОбжекты:
Код AS1/AS2:

public function draw(source:IBitmapDrawable, matrix:Matrix = null, ...

Ваше представление о том, что Интерфейсы - только памятка разработчику в команде, очень далеко от действтельности. Это их тридевятое применение. Интерфейсы - один из основных инструментов ООП. При взаимодействии одного класса с другим важно не то, какой это класс, а реализует ли он необходимые для этого взаимодействия методы, то есть - Интерфейс. Сами классы могут быть совершенно разными. Ситуации бывают такими, когда эти классы могут быть и дисплейными и логическими, или базами данных, но поддерживать один интерфейс - например, сериализацию для сохранения их состояния.
Пример - сейвы в игре. Вам надо описать в этом сейве состояние сотни объектов, четверть которых вообще не является дисплейными, например списки инвентаря, и имеет абсолютно разные параметры для сохранения. Все они должны иметь метод serialize():XML (XML это к примеру, формат тут не важен, но он один для всех). Менеджер сохранений проходится по списку подлежащих сохранению объектов и запрашивает у каждого сериализацию - некий набор данных, описывающий все параметры, необходимые для последующего восстановления текущего состояния этого объекта. Классы - самые разные. Все, что требуется - реализация интерфейса, т.е. наличие метода serialize, возвращающего данные в условленном формате. Ясно понятно, что Вы не будете наследовать сто совершенно РАЗНЫХ классов от одного - у Вас это просто НЕ ПОЛУЧИТСЯ, потому что наследование идет только по цепочке. Но Вы можете задать всем этим классам отдельный тип - интерфейс, гарантирующий наличие у них метода для общения с менеджером сохранений. "Гарантирующий" потому, что Класс не будет скомпилирован, пока в нем не будет метода, требуемого Интерфейсом.

TanaTiX 17.10.2010 22:00

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

Я правильно понял? Или еще не дошло?

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

Котяра 17.10.2010 23:47

У интерфейсов есть один недостаток - это усложнение ревью/ревизии кода, хотя это касается не только интерфейсов, но и использования в качестве аргументов базовых классов (особенно если они во многом абстрактны)
Тяжело без реальной sequence diagramm понять какой код выполняется.

Wolsh 18.10.2010 00:01

На самом деле, насколько я знаю, Flash-девелоперы интерфейсами пользуются довольно редко. Все-таки смысл их раскрывается только в более-менее сложных ООП-проектах, да и традиционное отношение сказывается)) Когда вы пять лет флешерили без интерфейсов, взять и вдруг начать ими пользоваться по полной слегка затруднительно.
Да, TanaTiX, все базовые предназначения Интерфейсов Вы перечислили. Надеюсь, новое понимание Вам когда-нибудь поможет)) Удачи!

expl 18.10.2010 00:42

Цитата:

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

    public class HintManager
    {
        ...
        public function addElement(element:*)//<-- здесь мы не можем указать тип,
                        //котрый устраивал бы и компонент,
                        //наследуемый от SimpleButton и компонент наследуемый от Sprite и
                        //имеющий при этом поле getHintText(),
                        //НЕ использовав интерфейс - нет других путей просто
        {
              ....
          var hintText:String = element["getHintText"]();

Тогда давай кодить на as1 уже.

Ну или более сурово:
Код AS3:

    public class HintManager
    {
        ...
        public function addElement(element:*)
 
        {
              ....
              if (element is MySimpleButton)
              {
                  (element as MySimpleButton).getHintText();
              }
              ele if (element is MySprite)
              {
                    (element as MySprite).getHintText();
              }
              ...
              // Теперь отстается только порадоваться тому, что если появится еще
              // какойнить элемент с getHintText(), наследованный от Shape или Bitmap
              // придется добавлять сюда еще одну веточку if-а

Интерфейс - это такой же тип как и класс, только свободный от рамок НЕмножественого наследования и от реализации.

iNils 18.10.2010 00:51

Цитата:

интерфейсы применяются там где:
- не справляется наследование,
Забудьте про связку наследование - интерфейсы. Это миф.

expl 18.10.2010 01:01

:eek:
Можно ссылочку поподробнее, где развенчивается этот миф?

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

А если нам надо расширить интерфейс(опять НЕ всмысле "интерфейс") класса в 2-х независимых веточках наследования - мы используем интерфейс (всмысле public interface ISomeInterface)

Как могут эти два понятия не быть связанными?

TanaTiX 18.10.2010 01:11

expl
Код AS3:

var button:IMyButton...

Я так понимаю аналогом данной конструкции без интерфейса было бы
Код AS3:

var button:*...

Т.е. мы не добавляем интерфейс на сцену, а просто даем понять, что у нас нет привязки к экземплярам определенного класса. Но с другой стороны получается что я не знаю что создаю. Странно как-то, не уютно.
iNils, а можно поподробней?

nOobCrafter 18.10.2010 01:21

Цитата:

получается что я не знаю что создаю
на выходе вы создаете обьект с неким нужным вам набором методов, которым можно пользоваться. По сути вам ведь это и надо, у него могут быть еще какие то методы, но в данный конкретный момент они не нужны и надо лишь то что описано в интерфейсе который этот обьект реализует.
Вам же приводили пример в меню, представим что у вас в меню каждая кнупочка уникальна, она выглядит не так как остальные, у нее анимация своя, но она реализует некий интерфейс, и у нее точно есть 2 метода show() И hide() для работы с кнупочками вам ведь больше и не надо?
опять же выше приведен пример с использованием метода serialize()...

TanaTiX 18.10.2010 01:33

nOobCrafter, я сейчас не столько по интерфейсу спросил и по примерам вроде все понятно. Хотя...
Вот я создаю некий объект button. Как я буду пользоваться его методами, когда у меня есть только названия методов? Мне их придется как-то переопределять? Я понимаю ситуации, когда речь идет о классах, но в указанной конструкции создается не класс, а его экземпляр, можно даже по сути сказать "экземпляр интерфейса". Или это я из контекста выдернул кусок и все с ног на голову перевернул? Смотрел на 8й пост.

iNils 18.10.2010 02:35

Цитата:

Можно ссылочку поподробнее, где развенчивается этот миф?
Можно. http://включи_свой_мозг
Каким образом интерфейс, не имеющий тела функций может реализовать множественное наследование?

Wolsh 18.10.2010 02:42

Цитата:

Я так понимаю аналогом данной конструкции без интерфейса было бы var button:*...
Ну не аналогом, а дешевым эрзацем... Прямой противоположностью, ибо смысл Интерфейса в том что методы четко определены, а смысл этой звездочки - "я понятия не имею, что это за класс и что у него за методы".
Потом в коде Вы пишете: button.label = "LOAD"; и компилятор вежливо кивает - "ну label так label, мне то откуда знать". А что потом будет в рантайме, покажет Error Message.
Начинающего программиста от продвинутого отличает то, что он никогда не ошибается. Начинающий программист верит в то, что конечно же передаст в этот параметр только то, что нужно. Чаще всего так и есть, ибо в двухстах строках трудно заблудиться))) В этой вере вся сила звездочки. Продвинутый программист не верит никому. Он устанавливает жесткие правила, чтобы ничто не могло пойти "не так". В этом смысл программирования. Не должно быть никаких неопределенностей. Если нельзя определиться с классом, поможет Интерфейс, но жесткую гарантию, что label у button есть, получить необходимо. Интерфейс может гарантировать наличие нужных методов и, если надо - наоборот скрыть ненужные, которые может и есть в Классе, но в данной ситуации не должны быть доступны.

iNils 18.10.2010 02:55

Вложений: 1
Интерфейс в картинках
Вложение 25333

Hidest 18.10.2010 16:20

Цитата:

Сообщение от TanaTiX (Сообщение 943436)
nOobCrafter, я сейчас не столько по интерфейсу спросил и по примерам вроде все понятно. Хотя...<...>Я понимаю ситуации, когда речь идет о классах, но в указанной конструкции создается не класс, а его экземпляр, можно даже по сути сказать "экземпляр интерфейса". <...>

Так вы и будете пользоваться определенными методами. Вы создаете не "экземпляр интерфейса" (что как бы смысла не имеет), а создаете экземпляр того класса, который имплементит данный интерфейс.

Фактически: var переменная:"Тип данных, который по-любому должен иметь определенный метод, какой он окажется в конце концов - не важно" = "Класс, который имплементит Интерфейс и имеет у себя уже реализованный необходимый метод".

dimarik 18.10.2010 16:32

Отсюда один из постулатов философии ООП. Программируйте в соответствии с интерфейсами, а не с реализацией.

samana 18.10.2010 18:08

На этом видео, показан интересный способ применения интерфейсов.

Psycho Tiger 18.10.2010 18:27

expl,
Цитата:

придется реализовывать этот метод и в MySimpleButton
SimpleButton final как бы.

Добавлено через 6 минут
@iNils:
Цитата:

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

Добавлено через 9 минут
@Автор: http://www.flasher.ru/forum/showthread.php?t=130250

dimarik 18.10.2010 18:39

Цитата:

SimpleButton final как бы.
Да вроде нет

iNils 18.10.2010 20:20

Цитата:

не очень вникал в сообщения, но вроде люди имели ввиду что AS3 поддерживает множественное наследование интерфейсов
Ну так вникни.

Psycho Tiger 18.10.2010 20:37

Цитата:

Сообщение от dimarik (Сообщение 943583)
Да вроде нет

Хм, и правда. Старею видимо.

AlexDesinger 19.10.2010 13:12

народ, может вопрос не в тему, но все же -
а чем отличается использование интерфейса, скажем от использования статического метода из разных мест, описанного в каком-нть классе?

Bgg 19.10.2010 13:17

Приехали.

arkadattx 19.10.2010 13:20

AlexDesinger, см. 14й пост

AlexDesinger 19.10.2010 15:16

хм...типо все дело в нетипизированных - типа "универсальных" переменных?

Psycho Tiger 19.10.2010 15:23

Нет, всё дело в инкапсуляции.

AlexDesinger 19.10.2010 16:55

Цитата:

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

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

-De- 19.10.2010 17:03

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

Psycho Tiger 19.10.2010 17:04

Интерфейс и статик методы - это как порше и Иосиф Кабзон. Можно одно в другом, а можно по отдельности.


Часовой пояс GMT +4, время: 16:28.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.