PDA

Просмотр полной версии : Конфликт имен статичной и обычной функций


cv'
06.07.2011, 18:56
Доброго вам, уважаемые flash-самураи!

Скажите, а есть ли решение (через namespace, например), при котором в одном классе может быть прописаны две функции с одним названием – статичная и обычная?
Типа вот так:

public class A
{
public static function test()
{
trace('static method');
}

public function test()
{
trace('instance method');
}
}

MXPain
06.07.2011, 19:01
нет, а зачем?

red_penguin
06.07.2011, 19:03
через namespace вроде можно, но только зачем?)

MXPain
06.07.2011, 19:05
как можно? нэймспэй для классов с одинаковым названием может быть разный а при чем тут функции то?

cv'
06.07.2011, 19:06
Исключительно ради красоты удобства использования.
Такая есть утилита, пользование которой можно реализовать как через статичные методы, но передавать в них десяток параметров, либо через экземпляр класса, и тогда передавать 1-2 параметра.

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

alatar
06.07.2011, 19:11
MXPain, для функций и полей класса может быть разный неймспейс.

MXPain
06.07.2011, 19:27
alatar спасибо, не юзал, буду знать)

cv'
06.07.2011, 19:28
А где можно посмотреть пример?.. В обычной документации я не нашел примера со статичными функциями.

goodguy
06.07.2011, 20:31
Тут есть пример http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/Namespace.html
Попробовал. Работает. Добавил static, ничего не изменилось. Так же работает.

MXPain
06.07.2011, 20:51
Hawaiian function hello():String {
return "aloha";
}

French function hello():String {
return "bon jour";
}

однако)

cv'
07.07.2011, 17:05
Я попробовал пример, но красоты особой не получилось.
Вот при таком коде

package
{
import flash.display.Sprite;
public class Namespace_Example extends Sprite
{
public function Namespace_Example()
{
var instance:StaticOrInstance = new StaticOrInstance();
var ns:Namespace = inst;
trace(instance.ns::test());
trace(StaticOrInstance.test());
}
}
}

namespace inst;

class StaticOrInstance
{

public static function test():String {
return "static function";
}

inst function test():String {
return "instance function";
}
}

Приходится вызывать функцию через .ns::, а это неудобно.
Хотелось бы решение при котором функцию можно было вызывать простым синтаксисом

trace(instance.test());
trace(StaticOrInstance.test());

Котяра
07.07.2011, 17:29
package
{

public class Base
{
public function test():void {
trace("instance!");
}

}

}
package
{

public class Child extends Base
{
public static function test():void {
trace("static!");
}
}

}
var ch:Child = new Child();
ch.test();
Child.test();

cv'
07.07.2011, 17:34
Вот это круто! Спасибо!

goodguy
07.07.2011, 17:59
А конфликтов имен так не возникает?
п.с. Самому тестировать в лом, поэтому справшиваю )

cv'
07.07.2011, 18:01
Протестировал. Все работает! Конфликта нет.
В базовом класе
public function test
в дочернем-
public static function test

goodguy
07.07.2011, 18:02
Хороший вариант. Уже вижу возможное практическое применение

Котяра
08.07.2011, 00:13
Честно говоря, считаю это быдлокодом.
ТО ЧТО ЗАПУТЫВАЕТ КОНЕЧНОГО ЧИТАТЕЛЯ ВАШЕГО КОДА - ЭТО ПЛОХО.
я понимаю что супер иде, переходы на определения.. но нетривиальные решения - это быдлокод, какими бы гениальными они не были бы.
BE SIMPLE!

goodguy
08.07.2011, 07:12
Честно говоря, считаю это быдлокодом.
У меня было пару раз, когда хотел использовать что-то подобное. Хотя, не спорю, без этого легко можно обойтись в любом случае

cv'
08.07.2011, 11:07
Честно говоря, считаю это быдлокодом.

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

i.o.
08.07.2011, 12:23
Вот специально проверил из первого поста пример.. Ну вот работает у меня и все тут. Что я не так делаю?

package
{
import flash.display.Sprite;

public class TestClass extends Sprite
{
public function TestClass()
{
trace("TestClass.()");

TestClass.doSomething();
this.doSomething();

var a:A = new A();
A.test();
a.test();
}

public static function doSomething() : void
{
trace("TestClass.doSomething() [static]");
}

public function doSomething() : void
{
trace("TestClass.doSomething() [instance]");
}
}
}


internal class A
{
public static function test() : void
{
trace('static method');
}

public function test() : void
{
trace('instance method');
}
}

Output:

TestClass.()
TestClass.doSomething() [static]
TestClass.doSomething() [instance]
static method
instance method

Ни ошибок, ни предупреждений. Разными FlexSDk: 4.1 и 4.5 Hero.

Bacrilio
08.07.2011, 12:39
var a:A = new A();
A.test();
a.test();

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

i.o.
08.07.2011, 12:44
Потому что ты в первый раз обращаешься к классу, а второй раз к объекту.
И что? Где конфликт то?

gloomyBrain
08.07.2011, 12:44
@Bacrilio
А Вы первый пост читали? =)

i.o.
08.07.2011, 12:46
Хотелось бы, чтобы методы при таком раскладе назывались одинаково, и все было в одном классе.
Цель достигнута. Вопрос закрыт. Не?

Bacrilio
08.07.2011, 13:01
@gloomyBrain
@Bacrilio
А Вы первый пост читали? =)

Разумеется !

...
Скажите, а есть ли решение (через namespace, например), при котором в одном классе может быть прописаны две функции с одним названием – статичная и обычная?
...

Это не ответ?


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


@i.o.
И что? Где конфликт то?

Я не говорил о конфликте, я описал почему НЕТ конфликта (компилиться, и работает так как хотелось).

Будьте внимательней пожалуйста ! Спасибо !

cv'
08.07.2011, 13:21
А конфликт очень простой: внутри класса А я не могу вызвать статичную функцию test, если есть обычная. При варианте с двумя классами - могу.

Bacrilio
08.07.2011, 13:31
@cv'
А конфликт очень простой: внутри класса А я не могу вызвать статичную функцию test, если есть обычная. При варианте с двумя классами - могу.


public class A
{
public static function test()
{
trace('static method');
}

public function test()
{
trace('instance method');
}
public function A(){
test(); //instance method
A.test(); //static method
}
}


Попробуйте. Это работает.

goodguy
08.07.2011, 13:32
А разве i.o. запостил не то же самое на предыдущей странице?

carrotoff
08.07.2011, 13:33
Господа, разъясните мне: зачем в одном классе 2 функции с одним и тем же именем, одна статичная, другая нет? Какое применение?

i.o.
08.07.2011, 13:38
А конфликт очень простой: внутри класса А я не могу вызвать статичную функцию test, если есть обычная
В чем заключается конфликт? Не компилируется? Вылетают ошибки во время выполнения кода?
Выше я вам привел полностью рабочий код, где не смог обнаружить никаких конфликтов.
Опишите вашу ситуацию подробнее.

cv'
08.07.2011, 13:39
О_О
И правда работает...
Вот вам и простое-правильное решение =)

Bacrilio
08.07.2011, 13:41
@goodguy
А разве i.o. запостил не то же самое на предыдущей странице?

В чем то да.
Но вопрос был про обращение в классе, а не про обращение к классу и объекту. Это немного разные "вещи", не так ли ?

cv'
08.07.2011, 13:57
Вот пример утилиты, которая это использует. (вложено) Она не претендует на абсолютность, но лично мне очень жизнь облегчает. Помогает выбирать из массива одни элементы и прятать другие. Я написал ее год назад, и почти в каждом flash проекте ей находится применение.

Синтаксис использования такой

public static function single(array:Array, index:int, select:Function, deselect:Function, deselectIfSelected:Boolean = false, deselectBeforeSelect:Boolean = false, forceDeselect:Boolean = false):void


Это очень удобно, если эту функцию надо вызвать 1-2 раза за весь проект. А если 4-5, уже становится как-то страшно. И тогда гораздо удобнее использовать экземпляр

pick = new Pick(array,select,deselect,lalala,blablabla);
pick.single(5);

i.o.
08.07.2011, 14:26
Но вопрос был про обращение в классе, а не про обращение к классу и объекту. Это немного разные "вещи", не так ли ?
Я так понимаю, это вы пропустили?

...
public function TestClass()
{
trace("TestClass.()");

TestClass.doSomething();
this.doSomething();
...

А чуть позже отвечаете практически этим же:

...
public function A(){
test(); //instance method
A.test(); //static method
}
...

Bacrilio
08.07.2011, 14:48
@i.o.
согласен, тут я недоглядел, приношу свои извинения.

i.o.
08.07.2011, 14:55
согласен, тут я недоглядел, приношу свои извинения.
бывает :)

cv', так получилось дописать функцию для экземпляра?

cv'
08.07.2011, 14:59
cv', так получилось дописать функцию для экземпляра?
Да, все получилось, спасибо! Пример выложил выше.

Aquahawk
09.07.2011, 13:34
Всем участвовавшим рекомендую ознакомиться с этой заметкой: Создание двух/трёх членов класса с одним именем (http://actualwave.com/blog/?p=55)

cv'
10.07.2011, 15:53
Всем участвовавшим рекомендую ознакомиться с этой заметкой: Создание двух/трёх членов класса с одним именем (http://actualwave.com/blog/?p=55)
Да, интересное решене с пустым неймспейсом. Спасибо!