Страницы

Поиск по вопросам

суббота, 14 декабря 2019 г.

Зачем нужны inner классы в интерфейсах в Java?

#java #ооп #интерфейс #inner


На мой взгляд, интерфейсы служат для разделения абстракции и реализации. Собственно,
зачем может понадобиться внутри интерфейса создавать класс, который будет обладать
некоторой реализацией?
Хотелось бы увидеть реальный пример использования внутренних классов в интерфейсах,
чтобы понять, как такая особенность Java может быть использована.
    


Ответы

Ответ 1



Пробежался структурным поиском по своему CLASSPATH и выловил следующие примеры: Интерфейс как пространство имен Самое частое - статический еnum, связнанный предметной областью с интерфейсом, объявленный внутри интерфейса. Интерфейс в данном случае играет роль пространства имен. public interface Foo { void foo(Bar bar); static enum Bar { BAR1, BAR2, BAR3 } } Пример: com.google.common.util.concurrent.Service Похожий вариант - класс, описывающий value-тип, связанный с интерфейсом. public interface Foo { void foo(Bar bar); static class Bar { private final String id; public Bar(Sting id) { this.id = id; } public String getId() { return id; } } } Пример: org.hibernate.persister.entity.Queryable io.undertow.security.api.AuthenticationMechanism Несколько маленьких классов внутри интерфейса реализующих другой очень узкий интерфейс. Интерфейс используется только как пространство имен. public interface Convertor { String convert(Object arg); } public interface Convertors { static class Convertor1 implements Convertor { String convert(Object arg) { /* ... */ }} static class Convertor2 implements Convertor { String convert(Object arg) { /* ... */ }} static class Convertor3 implements Convertor { String convert(Object arg) { /* ... */ }} } Пример: org.hibernate.tuple.TimestampGenerators Исключение, связанное с интерфейсом. public interface Foo { void foo() throws BarException; static class BarException extends Exception { // ... } } Пример: org.hibernate.boot.spi.InFlightMetadataCollector Интерфейс объявляет внутри себя вспомогательные helper-классы с логикой, которые предлагает использовать реализациям. Пример: org.eclipse.jetty.io.ByteBufferPool com.mysql.jdbc.SocketMetadata (5.1.39) Интерфейс объявляет внутри себя готовую реализацию-заглушку. public interface Foo { Bar foo(); static class FooImpl implements Foo { @Override public void foo() { return null; } } } Пример: org.junit.Test com.codahale.metrics.MetricRegistryListener Интерфейс объявляет внутри себя Singleton, потому что "почему бы и нет": и так антипаттерн, так хоть локализовать его. Пример: org.asynchttpclient.channel.ChannelPoolPartitioning Аннотация + обработчик Статический класс реализующий некий интерфейс внутри интерфейса-аннотации описывающий логику этой аннотации. Код, анализирующий аннотации скорее всего доберется до этого статического класса через рефлексию. @Retention(RetentionPolicy.RUNTIME) public @interface Foo { // annotation fields static class FooHandler implements Handler { public void handle(Foo foo, Object arg) { //... } } } public interface Handler { void handle(A a, Object arg); } Примеры: javax.annotation.RegEx javax.annotation.Nonnull javax.annotation.Nonnegative

Комментариев нет:

Отправить комментарий