"Conceptualmente, lo bueno es una interfaz si no puede confíe en el contrato que proporciona "dijo Erik.
Eso es cierto, pero hay otra consideración: se pueden esperar objetos de diferentes clases que se ajusten a algunas propiedades o métodos incluidos en una interfaz para procesarlos de forma segura probando qué propiedades o métodos se implementan.
Este enfoque se puede cumplir con frecuencia en Objective-C o Swift Cocoa para el cual el "protocolo" - equiv de "interfaz" - permite definir como "opcional" una propiedad o un método.
La instancia de los objetos se puede probar para comprobar si se ajustan a un protocolo dedicado.
// 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
Se puede verificar la implementación de un método (incluyendo getter y setter).
// Objective C
[instance respondsToSelector:@selector(MethodName)] => BOOL
// Swift (uses an optional chaining to check the implementation)
if let result = instance?.method…
El principio permite utilizar métodos que dependen de su implementación en objetos desconocidos pero que se ajustan al protocolo.
// 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 no permite hacer “opcional” en un elemento de una interfaz pero permite hacer algo gracias muy similares a la interfaz de extensión
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() {
…
}
}
Entonces casos pueden ser probados como “instancia de” ambos ProtocolBase para ver si el objeto se ajusta al "protocolo general" y a uno de los "protocolos subclase" para ejecutar selectivamente el método correcto.
Si bien delegate es una instancia de Class1 o Class2, parece ser una instancia de ProtocolBase y una instancia de PBMethodA o PBMethodB. Entonces
if (delegate instance of PBMethodA) {
res = ((PBMethodA) delegate).methodA(param);
} else if (dataSource instanceof PBMethodB) {
res = ((PBMethodB) delegate).methodB();
}
Hope this helps!
Parece que tiene que hacer varias interfaces: en términos conceptuales, ¿de qué sirve una interfaz si no puede confiar en el contrato que proporciona? – Erik
Esto socava por completo el punto de una interfaz. A menos que quiera que el compilador decida si la interfaz debe tener el método en tiempo de compilación, revise todas las implementaciones para anulaciones ... Ya no, mala idea – Spidy
@Spidy - Yo diría que no. El patrón de tener métodos de interfaz opcionales se usa muy comúnmente y de manera bastante efectiva en Objective-C. Los métodos opcionales pueden ser No-op. – user491880