Переопределение метода в экземпляре Java-объекта
================================================

Я хотел бы переопределить метод в объекте, который передал мне фабрика, над которой у меня мало контроля.

Моя конкретная проблема заключается в том, что я хочу переопределить**getInputStream** а также**getOutputStream** из**Сокет объект** выполнять**каротаж проводов**.

Общая проблема заключается в следующем:

Где я хотел бы взять экземпляр`Foo` и заменить`doBar` с моим, который будет работать следующим образом:

Для розетки я собираюсь вернуть**InputStream** а также**OutputStream** которые обернуты регистрацией, чтобы перехватить данные.

Поскольку Java использует OO на основе классов, это невозможно. Что вы можете сделать, это использовать[шаблон декоратора](https://en.wikipedia.org/wiki/Decorator_pattern)то есть написать оболочку для объекта, который возвращает упакованные потоки.



Я думаю, что есть способ достичь желаемого эффекта. Я видел, как она обычно использовалась в свинге с кнопками, чтобы позволить программисту заставить кнопку что-то делать при нажатии.

Скажем, у вас есть класс Foo:

Тогда у вас есть класс бегуна или что-то подобное. Вы можете переопределить метод doBar () в момент его создания, и он будет влиять только на этот конкретный объект.

этот класс может выглядеть так:

Я не совсем уверен, что это поможет вам, но, возможно, это укажет вам правильное направление. Если ничто иное не возможно переопределить метод вне класса, возможно, это поможет вам.



Вы не можете заменить методы в существующих объектах - вы не можете изменить тип существующего объекта, с одной стороны.

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

В вашем реальном случае нет способа, которым вы можете просто сделать отдельный вызов, чтобы обернуть потоки, возвращаемые сокетом? А можно поподробнее.



Вы не можете реально изменить объект на лету в Java.

Вы можете иметь что-то, что делать, что вы хотите, завернув`Foo` в другой подобный объект, который будет делегировать каждый вызов`Foo` и в этом же журнале все, что вы хотите. (увидеть[`Proxy`](https://download.oracle.com/javase/6/docs/api/java/lang/reflect/Proxy.html))

Но если вы хотите заняться ведением журнала, возможно, аспект является лучшим выбором. (увидеть[AspectJ](https://www.eclipse.org/aspectj/))



Я не уверен, возможно ли это. Рассматривали ли вы создание собственного класса, возвращение фабрикой объекта в качестве члена, а затем написание метода doBar () для этого класса.



Использование декоратора - правильный путь:

Некоторый очень похожий код к требованию, которое у вас есть с сокетами, здесь:

<http://www.javaspecialists.eu/archive/Issue058.html>



Другое решение, связанное с проксированием: вы можете использовать Аспекты, чтобы переопределить метод для данного объекта, не помещая его в подкласс. Это особенно уместно и распространено для регистрации. В этом примере используется spring-aop.



Если бы Socket был интерфейсом, то вы могли бы создать динамический прокси. Ниже приведен пример. Я поместил это здесь на случай, если другие люди должны будут сделать это, и целевой экземпляр является экземпляром интерфейса.

Основная причина, по которой это не сработает для Socket, заключается в том, что`java.lang.reflect.Proxy.newProxyInstance` для второго аргумента требуется массив интерфейсов, поэтому классы здесь не будут работать. Таким образом, для этого примера мне пришлось создать интерфейс под названием`ParentInterface`, который просто имеет три метода печати.



два варианта:

легко: если вы используете интерфейс Foo, вы можете использовать[Динамический прокси](https://download.oracle.com/javase/1.3/docs/guide/reflection/proxy.html) добавить новый функционал.больше работы: у вас есть «обходной» совет АОП - вы можете использовать любой из существующих инструментов АОП, чтобы сделать это возможным. Spring Framework может сделать это за вас, если вы уже используете его.