"Conceptually, what good is an interface if you cannot rely on the contract it provides" said Erik.
That's true but there is an other consideration: One can expect objects of different classes conforming to some properties or methods included in an interface to securely process with them by testing which properties or methods are implemented.
This approach can be frequently meet under Objective-C or Swift Cocoa for which the “protocol” — equiv of “interface” — allows to defined as “optional” a property or a method.
Instance of objects can be tested to check if they conform to a dedicated protocol.
// 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
The implementation of a method (including getter and setter) can be checked.
// Objective C
[instance respondsToSelector:@selector(MethodName)] => BOOL
// Swift (uses an optional chaining to check the implementation)
if let result = instance?.method…
The principle allows to use methods depending on their implementation in unknown objects but conforming to protocol.
// 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 does not allow to make “optional” an item in an interface but it allows to do something very similar thanks to interface extension
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() {
…
}
}
Then instances can be tested as “instance of” both ProtocolBase in order to see if object conform to the “general protocol” and to one of the “subclassed protocols” to execute selectively the right method.
While delegate is instance of Class1 or Class2 it appears to be instance of ProtocolBase and either instance of PBMethodA or PBMethodB. So
if (delegate instance of PBMethodA) {
res = ((PBMethodA) delegate).methodA(param);
} else if (dataSource instanceof PBMethodB) {
res = ((PBMethodB) delegate).methodB();
}
Hope this helps!
@optional
or@required
and test if a object responds to such methods before calling it – Procrustean@interface
s" quite differently. They are not 1-to-1 analogous in my opinion. The Objective-C counterpart more resembles classes with (pure) virtual methods in C++ rather than interfaces in Java, in my opinion. – Concomitance