Необязательный метод в интерфейсе Java - PullRequest
20 голосов
/ 11 марта 2011

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

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

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

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

Ответы [ 4 ]

22 голосов
/ 11 марта 2011

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

14 голосов
/ 11 марта 2011

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

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

7 голосов
/ 12 марта 2011

Хотя я согласен с другими ответами, следует отметить, что такие дополнительные методы существуют в 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();
4 голосов
/ 19 мая 2016

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

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

Этот подход часто встречается в Objective-C или Swift Cocoa, для которых «протокол» - эквивалент «интерфейса»»- позволяет определить как« необязательное »свойство или метод.

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

// 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

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

// 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() {
    …
    }
}

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

Хотя делегат является экземпляром класса 1 или 2, он представляется экземпляром ProtocolBase и экземпляром PBMethodA или PBMethodB.Так что

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...