I have an interface with several method definitions, and I would not like to require some of them.
Is this possible? if so, how can i implement this
"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!
You can have an Abstract class that implements this interface with empty function implementations and then extend from the Abstract class
Having said that, I would question why you need to do this. Maybe you need to split you interface into multiple smaller ones and implement the only ones that you need for a class
Although I agree with the other answers, one should note that such optional methods exist in the JDK. For example, List.add() is optional. Implementations must throw an UnsupportedOperationException if they don't want to implement this method.
If you want to be able to know if the optional method is implemented or not, then you could add another method (not optional) :
/**
* 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();
There is no @Optional
annotation in Java. One thing you can do is to create an interface, and then create an abstract class that provides stub implementations. Your classes can then extend this base class and override the methods they are interested in.