![]() |
Перегрузка методов в 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 подобного нет, рассмотрю любой язык, если он умеет это или что-то наподобие. |
Полиморфизм C# не подойдёт? [url]https://msdn.microsoft.com/ru-ru/library/ms173152.aspx[/url] |
практически любой динамический язык позволяет такое (питон, жабаскрипт) из статических такое можно изобразить в java * используя AOP * играясь с байткодом * изобразив прокси (штатная штука но работает только с интерфейсами) |
и да, в любом случае ты хочешь изощренно отстрелить ногу |
3-wayerr > [I]и да, в любом случае ты хочешь изощренно отстрелить ногу [/I] Само собой, это извращение. Но нужно для дела. AOP - это [url]http://en.wikipedia.org/wiki/Aspect-oriented_programming?[/url] Спасибо, почитаю. |
>Само собой, это извращение. Но нужно для дела. такое бывает нужно лишь когда есть скомпилированная баблиотека которую надо "хакнуть", во всех остальных случах использования можно избежать >AOP - это да, читать там особо нечего, это тухнология для "массового перекрытия" методов по произвольным критериям (гдето по режекспам), вот пример: [url]http://www.mkyong.com/spring/spring-aop-examples-advice/[/url] (раздел 4. Around advice) |
5-wayerr > [I]во всех остальных случах использования можно избежать[/I] Но не тогда, когда работаешь над магистерским дипломом :-) там требования заданы жестко на уровне кафедры. Вот и ищу способы обойти. |
а если этот класс TCar задекорировать, а там уже реализовать хоть стратегию хоть что? |
6-NTFS_ > Что это за требования такие? Рекомендую переосмыслить ваш алгоритм, наверняка есть способы проще и элегантнее решения поставленной задачи. А то ведь за деяния воздастся! =) |
8-40KHYTbIU >автор же писал что это требования к магистерскому диплому. Так что там может быть всякое ) |
9-ipp > Меня интересуют конкретные ограничения. Так как автор сперва сказал что хорошо бы иметь такую возможность для его "алгоритма", а потом какие не понятные ограничения всплывают. Надо прояснить вопрос. У меня есть уверенность, что решить вопрос можно иначе. |
Задача: изучение технологий расширений функций класса без использования наследования и изменения исходного кода. Язык программирования: любой. То есть, всего-то выглядит так - есть метод, нужно, чтобы над объектом сделать сильное колдунство, после чего этот метод будет работать иначе - и чтобы это изменение было обратимым. В цивилизованных случаях, это решается паттерном Стратегия или Прокси, как уже говорилось выше. Но случай нецивилизованный - код менять нельзя, создавать наследника нельзя. |
Бггг! Великий и могучий С++ - переписывай виртуальную таблицу на лету. :) |
11-NTFS_ > Задача: изучение технологий расширений функций класса без использования наследования и изменения исходного кода. жабаскрит лучше всего, там прототипирование вместо наследования 8) |
ну или простой прокси на java решается [url]https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/Proxy.html[/url] - стандартными средствами без всякого колдунства |
[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 Так нормально? |
Я кстати предложил реальный вариант. |
Спасибо всем ответившим, как выяснилось, задание было неверно понято :-) никаких ограничений нет, можно делать одним из моих любимых паттернов, без опускания до уровня VMT и прочей чертовщины :-) Повторный опрос клиента - это магия :-) |
Текущее время: 23:53. Часовой пояс GMT +3. |