2010-08-03 73 views
10

1)爲什麼在Java包中的文件中,我應該寫一個「包」的東西呢?它不是間接地假設它是在目錄中,還是在包中呢?爲什麼「包裝」關鍵字和.h?

2)我來自C++世界。我總是從其他使用該類的文件中導入我需要的.h類(我的意思是,我只想「顯示」標題,而不是實現)。但是現在我對Java中的導入有點困惑。這在Java中如何完成?

感謝

回答

7
  1. 不,這不是假設。畢竟,什麼是我的包叫什麼名字?com.mypackage.stuff?的rc.com.mypackage.stuff? myproject.com.mypackage.stuff? C.Users.makakko.workspace.myproject.src.com.mypackage.stuff?

    如果您只是將文件夾從文件夾中取出,它是否與驅動器根目錄相關?如果該項目是在另一臺機器上的另一個驅動器號上開發的,該怎麼辦?它相對於javac.exe的位置嗎?再一次,不同的安裝目錄呢?運行javac時工作目錄怎麼樣?但是你可以指定一個javac的位置來查找你的源文件。如果你想做一個簡單的測試程序,或者教某個從未編程過的Java的話,該怎麼辦?你必須使用/解釋包裝結構的整個概念嗎?

    如果您省略package說明符,那麼您仍然在包中。這只是「默認包」,沒有名字。

  2. 頭文件更像是一種來自C編譯方式的工件,而不是一種實現信息隱藏的方式。在C中,必須定義一個方法才能引用它。如果你想有幾個相互引用的方法,你必須在使用它們之前定義所有的方法,因此標題。 C++中的頭文件繼承於此,但C++中的更改改變了頭文件的必要性。

    在Java中,編譯器會在做任何需要方法/類的東西之前查看所有的方法和類簽名。頭文件提供的函數被放入編譯器本身。你可以不依賴於你的信息隱藏的頭,因爲

    1. 代碼可以除非你使用真實信息隱藏,如獨立的庫放在一個頭文件

    2. 內,程序員可以去找到與頭部匹配的c/cpp文件沒有問題

    同樣在Java中,您只能通過刪除源來獲取真實的信息隱藏。一旦使源代碼無法訪問,您就可以使用公共/受保護的類,枚舉和接口公開API。要獲得獎勵積分,請爲所有內容撰寫解釋性JavaDoc註釋,並在您的源代碼上運行javadoc.exe,以便爲使用您的軟件包的任何人制作單獨的文檔。

+0

AFAIK包名稱始終是冗餘的。只要試着將'com.mypackage.stuff'改成* any * else就可以在不改變'CLASSPATH'的情況下編譯它。 – maaartinus 2014-04-16 22:48:36

5

1)package聲明必須匹配該項目的目錄層次結構。

如果我在Car.java中使用package com.stackoverflow.bakkal;,則預計會出現以下層次結構。

com/ 
|-- stackoverflow/ 
| `-- bakkal/ 
|  |-- Car.java 

2)如果你想隱藏就可以在Java中使用interface代替class的實現。然後例如在.class文件或JAR中分發實際的實現。

嗯但接口不能被實例化 ...

接口工作方式類似於C++中的原型到一定程度。你有合同,那麼實際的執行來自其他地方。

我想實例化一個類,但 沒有給出實施, 只有原型

這是不可能的,即使C++,你怎麼能實例化,而無需其實際執行的東西嗎?在C++中,你仍然需要鏈接到對象文件。在Java中,您使用.class文件。

+1

1)我的問題是爲什麼它沒有假設? :S 2)嗯,但一個接口不能instanciated ...我想實例化一個類,但沒有給予實現,只有原型。 – makakko 2010-08-03 02:37:21

+0

@makakko:只要.java文件可用,實現將始終可用。期。如果你想隱藏實現,只給用戶/程序員/ ET ET.class文件(或者包含.class的.jar)。確保你包含文檔,但。 – 2010-08-03 03:00:58

+0

謝謝Brian,我明白了。 :)。順便說一下,.class可以用一種「很好」的方式反轉,我的意思是,恢復原來的「名稱」變量/函數?因爲我猜Java MV不能處理類成員或函數的「偏移量」...... – makakko 2010-08-03 04:26:40

3

軟件包沒有被假定,因爲Java的哲學是明示比隱含/假設更好。

它確實能夠訪問當前包中的任何內容,但外部任何內容都需要顯式導入。 (我相信Java.lang是一個例外,因爲它包含了很多基本功能,例如String,所以不會有一個不會使用它的包)。

這也就是爲什麼你會看到:的

import java.util.ArrayList; 
import java.util.LinkedList; 

代替:

import java.util.*; 

這似乎惱人的,直到有一天,你正在試圖找出別人的代碼,並將其打如果事情被隱藏/暗示,你會變得多難。

如果您使用Eclipse,Netbeans或IntelliJ,您將永遠不會注意到,因爲有兩個功能。

首先,如果您在鍵入類名的過程中點擊ctrl-space,它不僅會爲您完成類名,還會自動將其添加到導入列表中。其次,如果你曾經進入導入錯誤的地方,或者你沒有使用ctrl-space擴展,你可以輸入ctrl-shift-o(eclipse)來讓它「修復導入」。這將自動導入需要導入的東西,並刪除不再需要的導入。根據您的設置,它也會展開或摺疊*。

一旦你得到一個系統,你甚至不會考慮導入。

1

包指定了類的路徑。它必須匹配磁盤上或jar(zip)中的目錄。位置相對於類路徑上的某個位置。受保護的訪問僅限於同一包中的類。

你可能在.h文件中做的一些事情是在類定義中完成的。常量屬於一個類,可能是公開可見的。在.h中,常量必須公開可見。

導入相當於包含.h,但有助於處理相同名稱的衝突定義問題。您只能包含一個項目或一個班級中的所有可見項目。也可以跳過導入並使用包名稱作爲您正在訪問的類的前綴。

通過導入實現並不是真正可見的(至少不會超出編譯類提供的範圍,可見的接口是public方法和數據,對於從相同的包方法和數據中導入,指定的(public/protected/private)也是可見的,受保護的方法和變量對類的子類是可見的,.h文件可以在不提供源文件或目標文件的情況下使用,Imports需要提供指定的類。僅包含常量,儘管這是被設計很差。)

+0

受保護的訪問意味着子類,而不是相同的包。包訪問(也稱爲「默認訪問」)通過省略任何訪問關鍵字(public/protected/private)來指定。 – 2010-08-03 02:58:26

+0

答案已更正。 – BillThor 2010-08-03 17:32:47

相關問題