2011-03-11 154 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