Каков пример утиной печати на Java?

Я недавно слышал о наборе уток, и я прочитал статью в Википедии об этом, но мне сложно перевести примеры на Java, что действительно помогло бы мне понять.

Кто-нибудь сможет дать ясный пример утиной печати на Java и как я могу ее использовать?

Java по дизайну не подходит для утиной печати. То, как вы можете это сделать, – это reflection:

public void doSomething(Object obj) throws Exception { obj.getClass().getMethod("getName", new Class[] {}).invoke(obj); } 

Но я бы защищал это на динамическом языке, таком как Groovy, где это имеет смысл:

 class Duck { quack() { println "I am a Duck" } } class Frog { quack() { println "I am a Frog" } } quackers = [ new Duck(), new Frog() ] for (q in quackers) { q.quack() } 

Справка

См. Это сообщение в блоге . Он дает очень подробный отчет о том, как использовать динамические прокси для реализации утиного ввода в Java.

В итоге:

  • создать интерфейс, который представляет методы, которые вы хотите использовать с помощью утиной печати
  • создайте динамический прокси-сервер, который использует этот интерфейс и объект реализации, который вызывает методы интерфейса на базовом объекте путем отражения (при условии соответствия подписей)

проверьте эту библиотеку :

 interface MyInterface { void foo(); int bar(int x, int y); int baz(int x); } public class Delegate { public int bar() { return 42; } } DuckPrxy duckProxy = new DuckPrxyImpl(); MyInterface prxy = duckProxy.makeProxy(MyInterface.class, new Delegate()); prxy.bar(2, 3); // Will return 42. 

С помощью утиного ввода интерфейса просто использовать динамический прокси , вы должны сопоставить имя метода и тип возвращаемого значения.

Java не реализует утиную печать.

С java 8 у вас есть 2 способа:

nº1: если вам нужен только один метод, используйте lambda

 static interface Action { public int act(); } public int forEachAct(List actionlist) { int total = 0; for (Action a : actionList) total += a.act(); } public void example() { List actionList = new ArrayList<>(); String example = "example"; actionList.add(example::length); forEachAct(actionList); } 

nº2: используйте анонимные classы (не очень эффективные, но в некоторых некритических частях это можно сделать)

 static interface Action { public int act(); public String describe(); } public void example() { List actionList = new ArrayList<>(); String example = "example"; actionList.add(new Action(){ public int act() { return example.length(); } public String describe() { return "Action: " + example; } }); } 

Ввод текста на Java является номинальным – совместимость основана на именах. Если вам нужны примеры того, как может выглядеть утка (или структурная типизация) в Java, посмотрите эту страницу: http://whiteoak.sourceforge.net/# Примеры, в которых приводятся примеры для программы, написанной в Whiteoak: Java- совместимый язык, который также поддерживает структурную типизацию.

Как правило, утиная печать используется с динамически типизированными языками. Вы проверяете во время выполнения наличие методов или свойств, необходимых для удовлетворения ваших потребностей, независимо от иерархии наследования.

Помимо использования рефлексии, которая будет казаться уродливой, самое близкое, что вы можете получить, – это использование минимальных интерфейсов, которые соответствуют критериям того, что вам нужно для утиной печати. Это сообщение в блоге хорошо описывает эту концепцию. Он теряет большую часть простоты утиного ввода в python или ruby ​​или javascript, но на самом деле это довольно хорошая практика на Java, если вы ищете высокий уровень повторного использования.

Хорошее определение:

Объекты являются полиморфными, не связанными с общим базовым classом или интерфейсом.

Справка

Я написал class утилиты для динамического создания декораторов для объекта. Вы можете использовать его для печати уток: https://gist.github.com/stijnvanbael/5965616

Пример:

 interface Quacking { void quack(); } class Duck { public void quack() { System.out.println("Quack!"); } } class Frog { public void quack() { System.out.println("Ribbip!"); } } Quacking duck = Extenter.extend(new Duck()).as(Quacking.class); Quacking frog = Extenter.extend(new Frog()).as(Quacking.class); duck.quack(); frog.quack(); 

Вывод:

 Quack! Ribbip! 

Поздно к вечеринке (как обычно), но я написал быстрый class для того, чтобы сделать какую-то утку, набирая себя. См. Здесь .

Он будет работать только с интерфейсами, но для примера использования:

 interface Bird { void fly(); } interface Duck extends Bird { void quack(); } class PseudoDuck { void fly() { System.out.println("Flying"); } void quack() { System.out.println("Quacking"); } } class Tester { @Test void testDuckTyping() { final Duck duck = DuckTyper.duckType(new PseudoDuck(), Duck.class); } } 

Поддерживает методы интерфейса по умолчанию, параметры, проверку Типы исключений совместимы и будут проверять все методы classа PseudoDuck (включая частные). Тем не менее, тестирование не проводилось с использованием общих интерфейсов.

  • Есть ли у C # способ дать мне неизменный словарь?
  • Почему Java 8 не обновляет 31 x64 с Chrome 42.0.2288.6 dev x64 на OS X 10.9.5?
  • WatchService для Java 6
  • Реверсирование связанного списка в Java, рекурсивно
  • Метод ContainArrayList
  • Lossless JPEG Rotate (90/180/270 gradleусов) в Java?
  • Java: бесконечный цикл с использованием Scanner in.hasNextInt ()
  • Erlang Process vs Java Thread
  • Как запустить Eclipse с использованием новой версии 1.7 для JDK для Mac?
  • Обработка InterruptedException в Java
  • Автоматическая проводка списка с использованием схемы util дает NoSuchBeanDefinitionException
  • Interesting Posts

    Приложение Gmail 5.0 не работает с «Разрешением, запрещенным для вложения», когда оно получает намерение ACTION_SEND

    Создание CSV-файла для Excel, как иметь новую строку внутри значения

    Как мы можем указать правила для плагина проверки правильности jquery по classу?

    Недопустимая форма Symfony2 без ошибок

    Что эквивалентно ActionBar в более ранних версиях sdk?

    Gson TypeToken с динамическим типом ArrayList

    Как начать намерение, передав ему некоторые параметры?

    Программное обеспечение для отслеживания использования Интернета на семейном компьютере

    Как отключить автоматический запуск экранной клавиатуры на Windows 7 64 бит?

    C # общий список как получить тип T?

    В чем смысл «не временных» обращений к памяти в x86

    Идея Intellij не может ничего разрешить в maven

    Получение странного IP-адреса с маршрутизатора

    cvc-complex-type.3.2.2 атрибуту ‘uuid’ не разрешено появляться в элементе ‘jasperreport’

    Буферизованные файлы (для более быстрого доступа к диску)

    Давайте будем гением компьютера.