Форум на Kuban.ru (http://forums.kuban.ru/)
-   Разработка программ (http://forums.kuban.ru/f1024/)
-   -   Перегрузка методов в runtime без наследования - возможно ли? (http://forums.kuban.ru/f1024/peregruzka_metodov_v_runtime_bez_nasledovaniya_-_vozmozhno_li-6478417.html)

NTFS_ 03.02.2015 10:26

Перегрузка методов в runtime без наследования - возможно ли?
 
День добрый.

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

Пример:

Класс TCar - имеет метод Speed, который возвращает его скорость (например, 20).

Я назначаю классу стратегию SFly - после чего в методе Speed возвращается большее число (35).

Если я назначаю новую стратегию STurbo - у него уже Speed возвращает 50.

При этом, метод Speed исходного класса Car - не меняется, это важно! Он по прежнему состоит из одной строки - return 20. То есть, стратегия должна поддерживаться средствами компилятора.

Наследование не подходит, ибо объект создается один раз.

Делать дополнительный класс TSpeed, который передается со стратегией, и возвращает нужное значение - тоже нельзя, исходный код метода Speed строго определен и не должен меняться.

Примерный псевдокод.

Car C = new Car()
Writeln(C.Speed()) ; // Выводит 20

AssignStrategy(C,SFly) ;
Writeln(C.Speed()) ; // Выводит 35

AssignStrategy(C,STurbo) ;
Writeln(C.Speed()) ; // Выводит 50

AssignStrategy(C,SFly) ;
Writeln(C.Speed()) ; // Выводит снова 35

ClearStrategy(C) ;
Writeln(C.Speed()) ; // Выводит 20


В ObjectPascal подобного нет, рассмотрю любой язык, если он умеет это или что-то наподобие.

SheLLest 03.02.2015 17:20

Полиморфизм C# не подойдёт?
[url]https://msdn.microsoft.com/ru-ru/library/ms173152.aspx[/url]

wayerr 03.02.2015 21:29

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

из статических такое можно изобразить в java

* используя AOP

* играясь с байткодом

* изобразив прокси (штатная штука но работает только с интерфейсами)

wayerr 03.02.2015 21:30

и да, в любом случае ты хочешь изощренно отстрелить ногу

NTFS_ 04.02.2015 19:41

3-wayerr >
[I]и да, в любом случае ты хочешь изощренно отстрелить ногу
[/I]
Само собой, это извращение. Но нужно для дела.

AOP - это [url]http://en.wikipedia.org/wiki/Aspect-oriented_programming?[/url]
Спасибо, почитаю.

wayerr 04.02.2015 23:01

>Само собой, это извращение. Но нужно для дела.

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

>AOP - это

да, читать там особо нечего, это тухнология для "массового перекрытия" методов по произвольным критериям (гдето по режекспам), вот пример: [url]http://www.mkyong.com/spring/spring-aop-examples-advice/[/url] (раздел 4. Around advice)

NTFS_ 05.02.2015 09:21

5-wayerr >
[I]во всех остальных случах использования можно избежать[/I]
Но не тогда, когда работаешь над магистерским дипломом :-) там требования заданы жестко на уровне кафедры. Вот и ищу способы обойти.

ipp 05.02.2015 22:32

а если этот класс TCar задекорировать, а там уже реализовать хоть стратегию хоть что?

40KHYTbIU 06.02.2015 00:10

6-NTFS_ > Что это за требования такие?
Рекомендую переосмыслить ваш алгоритм, наверняка есть способы проще и элегантнее решения поставленной задачи. А то ведь за деяния воздастся! =)

ipp 06.02.2015 13:56

8-40KHYTbIU >автор же писал что это требования к магистерскому диплому. Так что там может быть всякое )

40KHYTbIU 06.02.2015 14:18

9-ipp > Меня интересуют конкретные ограничения. Так как автор сперва сказал что хорошо бы иметь такую возможность для его "алгоритма", а потом какие не понятные ограничения всплывают. Надо прояснить вопрос. У меня есть уверенность, что решить вопрос можно иначе.

NTFS_ 06.02.2015 15:46

Задача: изучение технологий расширений функций класса без использования наследования и изменения исходного кода.
Язык программирования: любой.
То есть, всего-то выглядит так - есть метод, нужно, чтобы над объектом сделать сильное колдунство, после чего этот метод будет работать иначе - и чтобы это изменение было обратимым.
В цивилизованных случаях, это решается паттерном Стратегия или Прокси, как уже говорилось выше. Но случай нецивилизованный - код менять нельзя, создавать наследника нельзя.

max 06.02.2015 20:08

Бггг! Великий и могучий С++ - переписывай виртуальную таблицу на лету. :)

wayerr 07.02.2015 01:12

11-NTFS_ > Задача: изучение технологий расширений функций класса без использования наследования и изменения исходного кода.

жабаскрит лучше всего, там прототипирование вместо наследования 8)

wayerr 07.02.2015 01:14

ну или простой прокси на java решается [url]https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/Proxy.html[/url] - стандартными средствами без всякого колдунства

40KHYTbIU 07.02.2015 10:58

[code]
public class Car **
public Double speed()** return 100D; **
**

class App **
public static void main(String[] args) **
Car carOne = new Car();
Car carTwo = new Car() **
public Double speed()** return 200D; **
**;
System.out.println("Speed of CarOne:"+carOne.speed());
System.out.println("Speed of CarTwo:"+carTwo.speed());
**
**
[/code]

Output:
Speed of CarOne:100.0
Speed of CarTwo:200.0

Так нормально?

max 07.02.2015 11:52

Я кстати предложил реальный вариант.

NTFS_ 07.02.2015 22:24

Спасибо всем ответившим, как выяснилось, задание было неверно понято :-) никаких ограничений нет, можно делать одним из моих любимых паттернов, без опускания до уровня VMT и прочей чертовщины :-)

Повторный опрос клиента - это магия :-)


Текущее время: 23:53. Часовой пояс GMT +3.