Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / Переменная как функция / 25 сообщений из 33, страница 1 из 2
14.10.2013, 12:14
    #38426343
X-Cite
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменная как функция
Добрый день.
Есть ли в Java возможность, как в Delphi, присвоить переменной процедуру(функцию) чтобы потом вызвать ее.

Пример:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
public class NewClass {
    
    public abstract void test;
    
    public void Exec(){
        test();
    }
    
}

public class NewClass2 {
    
    public void Method(){
        NewClass my;
        my.test = Show;
        my.Exec();
    }
    
    public void Show(){
        // тут делаем то что надо
    }
}
...
Рейтинг: 0 / 0
14.10.2013, 12:23
    #38426367
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменная как функция
По-простому нет.
Есть Reflection API - Method.invoke()
Есть MethodHandler, назначение которого не особо понятно.
Есть всяческие утилиты работы с JavaBeans, которые скрывают рутину Reflection API.
Есть Guava, которая позволяет писать в более функциональном стиле (ведь обычно в этом случае нужна ссылка на функцию)
На подходе Java 8 с лямбдами и функциональными интерфейсами. Не совсем аналог ссылки на метод, но можно реашить готовыми классами в гораздо более простом стиле.

Для выбора правильного решения нужно понять зачем вам это понадобилось.
...
Рейтинг: 0 / 0
14.10.2013, 12:27
    #38426381
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменная как функция
Аа... ну и совсем забыл. Можно тупо обернуть желаемый код в анонимный класс Callable/Runnable и его исопльзовать как ссылку на этот код.
...
Рейтинг: 0 / 0
14.10.2013, 12:34
    #38426390
X-Cite
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменная как функция
BlazkowiczДля выбора правильного решения нужно понять зачем вам это понадобилось.
Скажем есть класс А в котором метод, который должен быть реализован в классе Б использующим класс А, но не унаследованном.
т.к. класс А может использоваться в 20 разных классах Б и каждый должен иметь свою реализацию метода класса А (например вывод на экран).

Раз такого нет, значит будем через наследование переопределять.
...
Рейтинг: 0 / 0
14.10.2013, 12:36
    #38426394
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменная как функция
Bridge? Две иерархии? Очень секретная предметная область, поэтому приходится объяснять на пальцах?
...
Рейтинг: 0 / 0
14.10.2013, 12:44
    #38426417
X-Cite
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменная как функция
Не совсем понял о чем вы.

Вообщем я реализовываю базовый абстрактный класс для трансформации XML сообщения из одного в второе. В этом классе будут указаны основные методы, часть из которых будут переопределены в наследнике.
Класс-наследник собственно будет отвечать за конкретную трансформацию.
Во время трансформации надо выводить сообщения.
Класс-наследник понятия не имеет куда ему выводить сообщения, т.к. его вызывает стороннее приложение. Поэтому идеология такая, что уже в стороннем приложении будет реализован этот метод, который будет выводить на экран. Ну и в стороннем приложении создается экземпляр класса-наследника.
...
Рейтинг: 0 / 0
14.10.2013, 12:52
    #38426437
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменная как функция
И обычный логгер никак не подходит? В каком виде сообщения?
...
Рейтинг: 0 / 0
14.10.2013, 13:06
    #38426467
Troglodit
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменная как функция
Есть, но в Java 8. Почитайте про lamda.
...
Рейтинг: 0 / 0
14.10.2013, 13:08
    #38426475
Troglodit
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменная как функция
А чем вас готовые логгеры не устроили типа log4j2, они расширяемы под любые нужды.Зачем велосипед?
...
Рейтинг: 0 / 0
14.10.2013, 13:12
    #38426490
X-Cite
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменная как функция
BlazkowiczИ обычный логгер никак не подходит? В каком виде сообщения?
Для стороннего приложения реализуется класс унаследованный от некоего класса предоставляемого библиотекой приложения.
Класс который мы реализовали, подключается в стороннем приложении и подхватывается.
Соответственно стороннее приложение предоставило свои методы для отображения информации.

Вообщем.
Приложение это SAP PI. Я реализовываю Java Mapping для него.
К проекту подключается библиотека SAPMapping и переопределяется класс и некоторые методы из библиотеки.
В некоторых методах параметрами выступают классы реализованные в библиотеке. Они и отвечают за вывод на экран.

Для того, чтобы не писать один и тот же код 100 раз, для 100 Mapping'ов. Я реализовываю собственную библиотеку, которая будет уметь преобразовывать XML сообщение из одного состояния в другое, но эта библиотека ничего не должна знать о библиотеке SAP.
Соответственно вызывать в ней функции реализованные в бибилотеке SAP мы не можем. Поэтому я хочу вызвать функцию абстрактно, чтобы она была реализована в проекте, который переопределил класс SAPи который использует мой класс для преобразования.

В целом я эту проблему (правда в J2ME) когда-то решал через Интерфейсы, попробую и сейчас сделать также.
...
Рейтинг: 0 / 0
14.10.2013, 13:14
    #38426496
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменная как функция
TrogloditЕсть, но в Java 8. Почитайте про lamda.
Есть ключевая разница в том что ссылку на любой метод в Delphi\C++ можно иметь как обычный указатель.
С лямдами такой финт не пройдёт. Ссылка на метод должна быть обязательно оформлена как типизированый функциональный интерфейс.
...
Рейтинг: 0 / 0
14.10.2013, 13:20
    #38426508
Troglodit
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменная как функция
BlazkowiczTrogloditЕсть, но в Java 8. Почитайте про lamda.
Есть ключевая разница в том что ссылку на любой метод в Delphi\C++ можно иметь как обычный указатель.
С лямдами такой финт не пройдёт. Ссылка на метод должна быть обязательно оформлена как типизированый функциональный интерфейс.
Я с этим не спорю, но на мой взгляд это самое близкое, т.е на 90%, т.к. сам смысл функциональный интерфейс-это интерфейс с ОДНИМ функ. методом, при этом вы можете передать ссылку на любой метод класса, который подходит в этом случае, имхо это очень похоже.
...
Рейтинг: 0 / 0
14.10.2013, 13:28
    #38426519
Troglodit
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменная как функция
X-CiteНе совсем понял о чем вы.

Вообщем я реализовываю базовый абстрактный класс для трансформации XML сообщения из одного в второе. В этом классе будут указаны основные методы, часть из которых будут переопределены в наследнике.
Класс-наследник собственно будет отвечать за конкретную трансформацию.
Во время трансформации надо выводить сообщения.
Класс-наследник понятия не имеет куда ему выводить сообщения, т.к. его вызывает стороннее приложение. Поэтому идеология такая, что уже в стороннем приложении будет реализован этот метод, который будет выводить на экран. Ну и в стороннем приложении создается экземпляр класса-наследника.
А что мешает в "Классе-наследнике" писать Logger.info("Message");
А в классе, который отвечает за отображение объявить Listener и делать всю логику по отображению.
...
Рейтинг: 0 / 0
14.10.2013, 15:10
    #38426748
rfq
rfq
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменная как функция
X-CiteНе совсем понял о чем вы.

Вообщем я реализовываю базовый абстрактный класс для трансформации XML сообщения из одного в второе. В этом классе будут указаны основные методы, часть из которых будут переопределены в наследнике.
Класс-наследник собственно будет отвечать за конкретную трансформацию.
Во время трансформации надо выводить сообщения.
Класс-наследник понятия не имеет куда ему выводить сообщения, т.к. его вызывает стороннее приложение. Поэтому идеология такая, что уже в стороннем приложении будет реализован этот метод, который будет выводить на экран. Ну и в стороннем приложении создается экземпляр класса-наследника.
Как вариант, объявите в базовом абстрактном классе абстрактный метод "вывСообщ". Оставьте его абстрактным в реализации. И уже в стороннем приложении определите.
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
// интерфейс
class Базовый {
  abstract void вывСообщ(String message);
  abstract void преобр(XML вход);
}

// реализация
class Наследник extends Базовый {
  void преобр(XML вход)  {
     вывСообщ(message);
  }
}

// стороннее приложение

Базовый преобразователь = new Наследник() {
  void вывСообщ(String message) {
    наЭкран(message);
  }
};

преобразователь.преобр(readXML);


И никаких функций-переменных не потребовалось.
...
Рейтинг: 0 / 0
14.10.2013, 16:26
    #38426876
ivanra
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменная как функция
X-CiteВ целом я эту проблему (правда в J2ME) когда-то решал через Интерфейсы, попробую и сейчас сделать также.
Судя по описанию задачи - шаблон Наблюдатель в чистом виде. И да, там нужны интерфейсы
...
Рейтинг: 0 / 0
14.10.2013, 16:32
    #38426889
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменная как функция
TrogloditЯ с этим не спорю, но на мой взгляд это самое близкое, т.е на 90%, т.к. сам смысл функциональный интерфейс-это интерфейс с ОДНИМ функ. методом, при этом вы можете передать ссылку на любой метод класса, который подходит в этом случае, имхо это очень похоже.
Близкое по синтаксису. А идеологически оно и без лямбд реализуется точно так же, через тот же Callable. Разницы нет.
...
Рейтинг: 0 / 0
14.10.2013, 16:37
    #38426899
X-Cite
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменная как функция
Получилось, что-то такое:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
public interface ILogger {

    public void ShowMessage(String aMessage);
    public void ErrorMessage(String aMessage);

}
public class SAPMappingCustom {

    protected ILogger logger;

    protected void ShowMessage(String aMsg) {
        if (logger != null) {
            logger.ShowMessage(aMsg);
        }
    }

    protected void ErrorMessage(String aMsg) {
        if (logger != null) {
            logger.ErrorMessage(aMsg);
        }
    }

    public void SetLogger(ILogger aLogger){
        logger = aLogger;
    }
}
//Класс внешнего приложения
public class MappingOrderCSVToJDBC extends AbstractTransformation implements ILogger{

    private SAPMapping sap = new SAPMapping();

    public void transform(TransformationInput ti, TransformationOutput to) throws StreamTransformationException {
        isRunSAP = true;
        sap.SetLogger(this);
        sap.блаблабла;
    }

    @Override
    public void ShowMessage(String aMessage) {
        if (isRunSAP) {
            this.getTrace().addInfo(aMessage);
        }
        else {
            System.out.println(aMessage);
        }
    }

    @Override
    public void ErrorMessage(String aMessage) {
        ShowMessage(aMessage);
        throw new RuntimeException(aMessage);
    }
}
...
Рейтинг: 0 / 0
14.10.2013, 16:45
    #38426922
X-Cite
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменная как функция
Жаль что в Java нет процедурного типа как в Delphi.
Реализовывать иерархию классов было бы намного гибче.
...
Рейтинг: 0 / 0
14.10.2013, 16:52
    #38426933
Лагман
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменная как функция
делаете кучу интерфейсов
Код: java
1.
 Callable1<RESULT, ARG1>{ RESULT call(ARG1 arg);}, Callable2<RESULT, ARG1, ARG2>, ....


делаете вместо методов поля

Код: java
1.
2.
3.
public final getFio = new Callable3<String, String, String, String>(){
	String call(String f, String i, String o) { return arg1 + " " + arg2 + " " + arg3; }
}



ссылаетесь на них
Код: java
1.
2.
3.
public void usage( Callable3<String, String, String, String> fioGetterOfObject ){
    fioGetterOfObject.call("Иванов","Иван","Иванович");
}
...
Рейтинг: 0 / 0
14.10.2013, 17:01
    #38426944
Лагман
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменная как функция
Однако стоит заметить что в итоге после хорошего рефакторинга нужда в этих костылях отпадает, ибо Java позволяет более гибко подойти к организации кода.
...
Рейтинг: 0 / 0
14.10.2013, 17:11
    #38426963
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменная как функция
X-CiteЖаль что в Java нет процедурного типа как в Delphi.
Реализовывать иерархию классов было бы намного гибче.
Жаль что Java не даёт наколбасить нечитаемое спаггети и требует более раздельного и строгого ООП подхода.
...
Рейтинг: 0 / 0
15.10.2013, 09:24
    #38427578
Usman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменная как функция
X-CiteЕсть ли в Java возможность, как в Delphi, присвоить переменной процедуру(функцию) чтобы потом вызвать ее.Такая возможность имеется. Через Reflection:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
public class TestMethodInvocation {
	
	public static void staticMethod(int i, String s) {
		System.out.println(i);
		System.out.println(s);
	}
	
	public void instanceMethod(double d, char c) {
		System.out.println(d);
		System.out.println(c);
	}

	public static void main(String[] args) throws Exception {
		TestMethodInvocation.class.getMethod("staticMethod", int.class, String.class).invoke(null, 1, "Hello");

		TestMethodInvocation tmi = new TestMethodInvocation();
		java.lang.reflect.Method m = tmi.getClass().getMethod("instanceMethod", double.class, char.class);
		m.invoke(tmi, Math.PI, '$');
	}
}
...
Рейтинг: 0 / 0
15.10.2013, 10:49
    #38427732
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменная как функция
X-CiteЖаль что в Java нет процедурного типа как в Delphi.
Реализовывать иерархию классов было бы намного гибче.
по справедливости, в дельфях делают через подписку класса на события.
Код: pascal
1.
2.
type
  TNotifyEvent = procedure(Sender: TObject) of object;


...впрочем, код на Delphi ты не показал.
...
Рейтинг: 0 / 0
20.10.2013, 23:55
    #38434892
avp.mk
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменная как функция
BlazkowiczНа подходе Java 8 с лямбдами и функциональными интерфейсами. Не совсем аналог ссылки на метод
MethodReference..

java 8 (instance method)
Код: java
1.
2.
3.
4.
5.
6.
7.
Block<String> aFunctionalInterface = System.out::println;
Arrays.asList("А", "B", "C", "D", "E").forEach(aFunctionalInterface);

Predicate<String> p = "Строка"::equalsIgnoreCase;
System.out.println(p.test("СТРОКА"));
System.out.println(p.test("строкА"));
System.out.println(p.test("Другая строка"));



java 8 (static method)
Код: java
1.
2.
3.
4.
5.
6.
7.
System.out.println(
    Arrays.asList("А", "Bb", "Ccc", "Ddddddddddddd", "Eeee")
    .stream()
    .map(s -> s.length())
    .reduce(Math::max)
    .get()
);




Ну и в байткоде (начиная с 7ой джавы) есть method handle (указатель на метод).
...
Рейтинг: 0 / 0
21.10.2013, 10:03
    #38435090
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменная как функция
avp.mkMethodReference..

Точно так же и в Java <8 реализуется через анонимный класс.

avp.mkНу и в байткоде (начиная с 7ой джавы) есть method handle (указатель на метод).
Оно есть не только в байткоде. Но с точки зрения удобства мало чем отличается от рефлексии.
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Переменная как функция / 25 сообщений из 33, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]