Подтвердить что ты не робот

Дополнительный метод в интерфейсе Java

У меня есть интерфейс с несколькими определениями методов, и я бы не хотел бы использовать некоторые из них.

Возможно ли это? если да, то как я могу это реализовать?

Я попытался установить аннотацию @Optional, но это не работает.

Должен ли я где-нибудь определять аннотацию Optional?

4b9b3361

Ответ 1

Хотя я согласен с другими ответами, следует отметить, что такие дополнительные методы существуют в JDK. Например, List.add() является необязательным. Реализации должны вызывать исключение UnsupportedOperationException, если они не хотят реализовывать этот метод.

Если вы хотите узнать, реализован ли дополнительный метод или нет, вы можете добавить другой метод (не обязательно):

/**
 * Returns true if optionalOperation() is supported and implemented, false otherwise
 */
boolean isOptionalOperationSupported();

/**
 * implements he foobar operation. Optional. If not supported, this method must throw
 * UnsupportedOperationException, and isOptionalOperationSupported() must return false.
 */
void optionalOperation();

Ответ 2

В Java нет аннотации @Optional. Одна вещь, которую вы можете сделать, это создать интерфейс, а затем создать абстрактный класс, обеспечивающий реализацию заглушек. Затем ваши классы могут расширить этот базовый класс и переопределить методы, которые они интересуют.

Ответ 3

У вас может быть класс Abstract, который реализует этот интерфейс с пустыми реализациями функций, а затем распространяется из класса Abstract

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

Ответ 4

"Концептуально, какой хороший интерфейс, если вы не можете полагаться на контракт, который он предоставляет", - сказал Эрик.

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

Этот подход часто встречается в Objective-C или Swift Cocoa, для которого "protocol" - equiv "interface" - позволяет определить как "необязательный" свойство или метод.

Экземпляр объектов можно протестировать, чтобы проверить, соответствуют ли они выделенному протоколу.

// Objective C

[instance conformsToProtocol:@protocol(ProtocolName)] => BOOL

// Swift (uses an optional chaining to check the conformance and the "if-let" mech)

if let ref: PrototocolName? = instance  => nil or instance of ProtocolName

Можно проверить реализацию метода (включая getter и setter).

// Objective C

[instance respondsToSelector:@selector(MethodName)] => BOOL


// Swift (uses an optional chaining to check the implementation)

if let result = instance?.method…

Принцип позволяет использовать методы в зависимости от их реализации в неизвестных объектах, но в соответствии с протоколом.

 // Objective C: example

if ([self.delegate respondsToSelector:@selector(methodA:)]) {
      res = [self.delegate methodA:param];

} else if ([self.delegate respondsToSelector:@selector(methodB)]) {
      res = [self.delegate methodB];

} …

 // Swift: example

 if let val = self.delegate?.methodA?(param) {
      res = val
} else if let val = self.delegate?.methodB {
      res = val
} …

JAVA не позволяет делать "необязательным" элемент в интерфейсе, но позволяет сделать что-то очень похожее благодаря расширению интерфейса

interface ProtocolBase {}
interface PBMethodA extends ProtocolBase {
    type methodA(type Param);
}
interface PBMethodB extends ProtocolBase {
    type methodB();
}

 // Classes can then implement one or the other.

class Class1 implement PBMethodA {
    type methodA(type Param) {
    …
    }
}
class Class2 implement PBMethodB {
    type methodB() {
    …
    }
}

Затем экземпляры могут быть протестированы как "экземпляр" обеих протоколов, чтобы проверить соответствие объекта "общему протоколу" и одному из "подклассовых протоколов" для выборочного выбора правильного метода.

В то время как делегат является экземпляром Class1 или Class2, он представляется экземпляром ProtocolBase и экземпляром PBMethodA или PBMethodB. Так

if (delegate instance of PBMethodA) {
    res = ((PBMethodA) delegate).methodA(param); 

} else if (dataSource instanceof PBMethodB) {
    res = ((PBMethodB) delegate).methodB();
}

Надеюсь, это поможет!