«Концептуально, чем хорош интерфейс, если вы не можете полагаться на контракт, который он предоставляет», - сказал Эрик.
Это правда, но есть и другое соображение: можно ожидать, что объекты разных классов соответствуют некоторым свойствам.или методы, включенные в интерфейс, чтобы безопасно обрабатывать их, проверяя, какие свойства или методы реализованы.
Этот подход часто встречается в 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();
}
Надеюсь, это поможет!