“从概念上讲,如果你不能依赖它提供的合约,那么接口有什么好处”,Erik 说。
确实如此,但还有其他考虑:人们可以期望符合接口中包含的某些属性或方法的不同类的对象通过测试实现了哪些属性或方法来安全地处理它们。
这种方法经常在 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
可以检查方法的实现(包括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() {
…
}
}
然后可以将实例作为 ProtocolBase 的“实例”进行测试,以查看对象是否符合“通用协议”和“子类协议”之一,以选择性地执行正确的方法。
虽然委托是 Class1 或 Class2 的实例,但它似乎是 ProtocolBase 的实例和 PBMethodA 或 PBMethodB 的实例。所以
if (delegate instance of PBMethodA) {
res = ((PBMethodA) delegate).methodA(param);
} else if (dataSource instanceof PBMethodB) {
res = ((PBMethodB) delegate).methodB();
}
希望这会有所帮助!