К списку форумов К списку тем
Регистрация    Правила    Главная форума    Поиск   
Имя: Пароль:
Рекомендовать в новости

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

banned
0 - 03.02.2015 - 10:26
День добрый.

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

Пример:

Класс 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 подобного нет, рассмотрю любой язык, если он умеет это или что-то наподобие.



1 - 03.02.2015 - 17:20
Полиморфизм C# не подойдёт?
https://msdn.microsoft.com/ru-ru/library/ms173152.aspx
2 - 03.02.2015 - 21:29
практически любой динамический язык позволяет такое (питон, жабаскрипт)

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

* используя AOP

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

* изобразив прокси (штатная штука но работает только с интерфейсами)
3 - 03.02.2015 - 21:30
и да, в любом случае ты хочешь изощренно отстрелить ногу
banned
4 - 04.02.2015 - 19:41
3-wayerr >
и да, в любом случае ты хочешь изощренно отстрелить ногу

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

AOP - это http://en.wikipedia.org/wiki/Aspect-...d_programming?
Спасибо, почитаю.
5 - 04.02.2015 - 23:01
>Само собой, это извращение. Но нужно для дела.

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

>AOP - это

да, читать там особо нечего, это тухнология для "массового перекрытия" методов по произвольным критериям (гдето по режекспам), вот пример: http://www.mkyong.com/spring/spring-...amples-advice/ (раздел 4. Around advice)
banned
6 - 05.02.2015 - 09:21
5-wayerr >
во всех остальных случах использования можно избежать
Но не тогда, когда работаешь над магистерским дипломом :-) там требования заданы жестко на уровне кафедры. Вот и ищу способы обойти.
Гость
7 - 05.02.2015 - 22:32
а если этот класс TCar задекорировать, а там уже реализовать хоть стратегию хоть что?
Гость
8 - 06.02.2015 - 00:10
6-NTFS_ > Что это за требования такие?
Рекомендую переосмыслить ваш алгоритм, наверняка есть способы проще и элегантнее решения поставленной задачи. А то ведь за деяния воздастся! =)
Гость
9 - 06.02.2015 - 13:56
8-40KHYTbIU >автор же писал что это требования к магистерскому диплому. Так что там может быть всякое )
Гость
10 - 06.02.2015 - 14:18
9-ipp > Меня интересуют конкретные ограничения. Так как автор сперва сказал что хорошо бы иметь такую возможность для его "алгоритма", а потом какие не понятные ограничения всплывают. Надо прояснить вопрос. У меня есть уверенность, что решить вопрос можно иначе.
banned
11 - 06.02.2015 - 15:46
Задача: изучение технологий расширений функций класса без использования наследования и изменения исходного кода.
Язык программирования: любой.
То есть, всего-то выглядит так - есть метод, нужно, чтобы над объектом сделать сильное колдунство, после чего этот метод будет работать иначе - и чтобы это изменение было обратимым.
В цивилизованных случаях, это решается паттерном Стратегия или Прокси, как уже говорилось выше. Но случай нецивилизованный - код менять нельзя, создавать наследника нельзя.
banned
12 - 06.02.2015 - 20:08
Бггг! Великий и могучий С++ - переписывай виртуальную таблицу на лету. :)
13 - 07.02.2015 - 01:12
11-NTFS_ > Задача: изучение технологий расширений функций класса без использования наследования и изменения исходного кода.

жабаскрит лучше всего, там прототипирование вместо наследования 8)
14 - 07.02.2015 - 01:14
ну или простой прокси на java решается https://docs.oracle.com/javase/8/doc...ect/Proxy.html - стандартными средствами без всякого колдунства
Гость
15 - 07.02.2015 - 10:58
Код:
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());
    **
**
Output:
Speed of CarOne:100.0
Speed of CarTwo:200.0

Так нормально?
banned
16 - 07.02.2015 - 11:52
Я кстати предложил реальный вариант.
banned
17 - 07.02.2015 - 22:24
Спасибо всем ответившим, как выяснилось, задание было неверно понято :-) никаких ограничений нет, можно делать одним из моих любимых паттернов, без опускания до уровня VMT и прочей чертовщины :-)

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


К списку вопросов
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск




Copyright ©, Все права защищены