2011-03-11 50 views
20

我有一个接口有几个方法定义,我想不是喜欢需要其中的一些。在Java接口中的可选方法

这可能吗?如果是这样,我该如何执行这个?

我试过设置一个@Optional的注释,但这似乎不起作用。

我需要在某处定义Optional注释吗?

+9

听起来像你需要制作几个接口 - 从概念上讲,如果你不能依赖它提供的合同,接口有什么好处。 – Erik 2011-03-11 20:36:27

+0

这完全破坏了界面的整个点。除非你希望让编译器通过检查覆盖的所有实现来确定接口是否应该在编译时使用该方法.... Ya不,主意不好 – Spidy 2011-03-11 20:41:15

+5

@Spidy - 我认为它不会。在Objective-C中,使用可选接口方法的模式非常普遍且非常有效。可选的方法可以是No-op。 – user491880 2012-08-15 05:45:32

回答

7

虽然我同意其他答案,但应该注意,JDK中存在这样的可选方法。例如,List.add()是可选的。如果实现不想实现此方法,则必须抛出UnsupportedOperationException。

如果你希望能够知道是否可选方法的实现与否,那么你可以添加其他方法(不可选):

/** 
* 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(); 
21

Java中没有@Optional注释。你可以做的一件事是创建一个接口,然后创建一个提供存根实现的抽象类。然后,您的类可以扩展这个基类,并覆盖它们感兴趣的方法。

12

你可以有一个空函数实现实现了这个接口的抽象类,然后不得不说,从抽象类

延伸,我会质疑你为什么需要这样做。也许你需要将接口拆分成多个较小的接口,并实现唯一需要的接口

+1

一个这样的例子是:'java.awt.event.MouseAdapter' – 2011-03-11 22:43:16

3

“从概念上讲,有什么好是一个接口,如果你不能依靠它提供的合同“,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(); 
} 

希望这有助于!

+0

... else if(delegate instanceof PBMethodB)...我猜? – Lemao1981 2016-05-19 05:33:48

+0

是的。精确。谢谢。 – 2016-05-19 08:29:58