|
|
|
Помогите с наследованием в генериках
|
|||
|---|---|---|---|
|
#18+
Вопрос такой. Какой тип должен быть у параметра, передаваемого в f(), при условии, что она может принимать ссылки на методы Foo и его наследников??? мне кажется, туда надо BiFunction<? extends Foo, String, Integer>, но компилятор не пускает. Подобрать методом перебора не вышло. Код: 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. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.07.2015, 22:45 |
|
||
|
Помогите с наследованием в генериках
|
|||
|---|---|---|---|
|
#18+
chabapok, Код: 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. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.07.2015, 02:04 |
|
||
|
Помогите с наследованием в генериках
|
|||
|---|---|---|---|
|
#18+
Не подходит. 1. Вы показали как сослаться на метод по объекту - но для этого нужен объект. Мне интересен способ сослаться по классу, т.к. объект в момент ссылания неизвестен. В учебнике https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html то что вы показали названо "Reference to an instance method of a particular object", а меня интересует "Reference to an instance method of an arbitrary object of a particular type" 2. Тут наверное больше непонятка из за того, что я не полностью покрыл примером то что хочется. Функция f() должна принимать ссылки на методы Foo и его наследников. Это значит, что если у нас в классе FooChild1 есть новая функция с подходящей сигнатурой, на нее тоже нужно, чтобы можно было сослаться: Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. ps. С ArrayList прокатывает такое: ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.07.2015, 08:23 |
|
||
|
Помогите с наследованием в генериках
|
|||
|---|---|---|---|
|
#18+
В предыдущем сообщении забыл запостить рассуждение про ArrayList. Канонический пример, если у нас есть ArrayList класса Foo или его наследников, выглядит как-то так: Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. Вообще, есть две конструкции: ? extends Foo - дает право присваивать ссылки на ArrayList с учетом наследования, но запрещает класть в него объекты ? super Foo - дает право класть в массив объекты, но ссылки можно присваивать только те, где T идет выше по иреархии наследования. Теперь посмотрим что у нас есть со ссылками на метод Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. Возможно, нужно комбинировать у Function второй и третий параметр как ? extends (или super) String - но у меня с этим тоже ничего не вышло. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.07.2015, 08:45 |
|
||
|
Помогите с наследованием в генериках
|
|||
|---|---|---|---|
|
#18+
Вообще, дело явно в первом параметре. Такое впечатление, что компилятор не поддерживает наследования в ссылках на метод. Я чуток упростил пример: Код: 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. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.07.2015, 09:03 |
|
||
|
Помогите с наследованием в генериках
|
|||
|---|---|---|---|
|
#18+
chabapok, Ну и вопросы у вас.. Задумываться приходится :) Тут, как бы, проблема не просто в method references, а глубже, в вариантности дженериков. http://stackoverflow.com/questions/2723397/java-generics-what-is-pecs Если "развернуть" ссылку на метод, получится что-то типа такого: Код: java 1. 2. 3. 4. 5. 6. 7. 8. Consumer - контравариантный тип, и требует использования супертипа, а не потомка. Вот так прокатит: Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.07.2015, 19:00 |
|
||
|
Помогите с наследованием в генериках
|
|||
|---|---|---|---|
|
#18+
ДиезConsumer - контравариантный тип, и требует использования супертипа, а не потомка. Такого понятия не существует в java. В какую сторону требуется наследование - определяется словом super или extends. К вашему примеру я приходил методом тыка. Это немножко не то, по той причине, что такой способ позволяет идти по ветке наследования вверх. Это относительно бесполезная фишка для Consumer-ов, она предназначена для контейнеров. В Consumer можно писать без super. Следующий пример компилится: Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. В контейнерах все хитрей, есть урок на русском по этой теме тут ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.07.2015, 22:32 |
|
||
|
Помогите с наследованием в генериках
|
|||
|---|---|---|---|
|
#18+
chabapokДиезConsumer - контравариантный тип, и требует использования супертипа, а не потомка. Такого понятия не существует в java. В какую сторону требуется наследование - определяется словом super или extends. Да, в Java нет явного указания, что параметр типа является ко- или контравариантным (как в Scala или c#). Но вариантность в широком смысле - это поведение типа, а не фича языка https://ru.wikipedia.org/wiki/Ковариантность_и_контравариантность_(программирование)#Java chabapokК вашему примеру я приходил методом тыка. Это немножко не то, по той причине, что такой способ позволяет идти по ветке наследования вверх. Это относительно бесполезная фишка для Consumer-ов, она предназначена для контейнеров. В Consumer можно писать без super. Следующий пример компилится: Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. В контейнерах все хитрей, есть урок на русском по этой теме тут ... Так что логично было бы предположить, что extends позволить идти по ветке наследования вниз. Но нет, со ссылками на метод это не работает. Принципиальной разницы между контейнерами и функциональными интерфейсами я не вижу - поведение generic-типов одинаковое. К Consumer<T> есть парный интерфейс Supplier<T> - он-то как раз позволяет использовать подклассы для параметризации: Код: java 1. 2. 3. 4. 5. 6. 7. 8. Рассматривайте Supplier как IN-коллекцию, а Consumer - как OUT-коллекцию. Код: java 1. 2. 3. 4. 5. Всё как в уроке :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.07.2015, 09:44 |
|
||
|
Помогите с наследованием в генериках
|
|||
|---|---|---|---|
|
#18+
chabapokНе подходит. Код: 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. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.07.2015, 03:00 |
|
||
|
Помогите с наследованием в генериках
|
|||
|---|---|---|---|
|
#18+
Usman, Во! Спасибо! Это оно! Походу, отвечая на вопрос из первого поста, обьявлять f() надо так: Код: java 1. 2. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.07.2015, 12:46 |
|
||
|
Помогите с наследованием в генериках
|
|||
|---|---|---|---|
|
#18+
chabapokUsman, Во! Спасибо! Это оно! Походу, отвечая на вопрос из первого поста, обьявлять f() надо так: Код: java 1. 2. Круто. А что теперь с этим делать? :) Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. Кроме null в вызове v.apply ничего не подставишь - ошибка компиляции. Т.е. смысл у данного решения нулевой, особенно в свете "Reference to an instance method of an arbitrary object of a particular type" ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.07.2015, 14:40 |
|
||
|
Помогите с наследованием в генериках
|
|||
|---|---|---|---|
|
#18+
Всё, беру свои слова назад :)) Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.07.2015, 15:55 |
|
||
|
|

start [/forum/topic.php?fid=59&msg=38997331&tid=2125199]: |
0ms |
get settings: |
4ms |
get forum list: |
18ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
40ms |
get topic data: |
11ms |
get forum data: |
2ms |
get page messages: |
46ms |
get tp. blocked users: |
1ms |
| others: | 214ms |
| total: | 340ms |

| 0 / 0 |
