2012-07-09 93 views
9

我正在創建一個Java庫,作爲打算將這個.jar分發給開發人員的最終產品。Java類範圍和庫

我正在從Objective-C「翻譯」我的庫,在那裏我控制開發人員可以使用哪些類頭文件。換句話說,我只向開發人員展示他們可以處理的幾個類。

在我的Java庫中,我正在使用包,而且我的包已經變得相當大。所以我決定把我的模型和控制器分成不同的包。但是現在我想保持私密的模型,我需要將其標記爲公開才能使用主包。

我的問題是這是否違揹我在Objective-C中做的事情?

例如,我有一個事件類,它實際上只在內部使用,我不希望用戶知道它或考慮它。我有另一個類TimedEvent,用戶可以得到一個管理的實例。

在我的Objective-C中,我只是從庫公共範圍中排除Event類,允許TimedEvent。

如果我在我的圖書館裏做的事情更加整潔,那麼看起來軟件包並不是這樣。從現在開始,我的主控制器在主包中,所有的模型都在另一個包中 - 被迫擁有公共範圍。

意見?

回答

5

這是可能的與Java,但是是有原因的(幾乎)沒有人做它...

如果你把實現和接口在同一個包,那麼你可以省略所有訪問修飾符(privateprotected,public)從類和方法給他們「默認」或「包」的可見性:只允許在同一個包中的類看到/使用它們。

缺點:您必須混合API和實現。

另一種方法是將實現移入包*.private.*。 API和實現不再混合,但惡意用戶可以輕鬆訪問實現 - 這只是一個命名約定。就像一個停車標誌:它意味着什麼(「小心」),但實際上並沒有阻止你。

最後,您可以在接口內部實現接口。例如:

public interface IFoo { 
    String getName(); 

    private static class Foo implements IFoo { 
     public String getName(); 
    } 

    public static class FooFactory { 
     public static IFoo create() { return new Foo(); } 
    } 
} 

醜,是不是?

+2

尼斯觸摸的界面中實現。這是一個新功能嗎? – 2012-07-09 14:12:23

+1

不,它支持內部類(1.2,我認爲),但它增加了很多的鍋爐代碼。 – 2012-07-10 08:00:22

+0

很多教科書都弄錯了這個。 「接口:常量和方法聲明」 – 2012-07-11 03:10:19

4

控制將類暴露給世界的常用方法是隱藏實現在接口和工廠之後的實現。

  • 創建界面爲你TimedEvent,併爲TimedEvent接口
  • 的創建實例的類放入主包的接口,廠家在一個子包
  • 給工廠公衆知名度
  • 實現子包的界面,給它包可見
  • 創建工廠實現TimedEvent接口的類的實例

這裏是你如何能做到這一個例子:

package com.my.main; 
public interface TimedEvent { 
    void fire(); 
} 

package com.my.main.events; 
import com.my.main; 
public class EventFactory { 
    public TimedEvent makeTimedEvent() { return new TimedEvent(); } 
} 
// TimedEventImpl has package visibility - it is not public. 
class TimedEventImpl implements TimedEvent { 
    public void fire() { 
     // Fire a timed event 
    } 
} 

的用戶會訪問TimedEvent這樣的:

com.my.main.events.EventFactory f = new com.my.main.events.EventFactory(); 
com.my.main.TimedEvent evt = f.makeTimedEvent(); 
evt.fire();