10. 內部類、源文件規則和包
1. 內部類
閱讀什麽是java內部類和Java中為什麽要使用內部類
內部類的兩個作用:
- 一般類,是不允許訪問另一個類的 private 權限的,但內部類可以。
-
可實現多重繼承。
靜態內部類可以直接創建對象new B.C(); 如果內部類不是靜態的,那就得這樣 B b = new B(); B.C c = b.new C();
2. 源文件規則
- 一個源文件中只能有一個public類
- 一個源文件可以有多個非public類
-
源文件的名稱應該和public類的類名保持一致。
例如:源文件中public類的類名是Employee,那麽源文件應該命名為Employee.java。
- 如果一個類定義在某個包中,那麽package語句應該在源文件的首行。
- 如果源文件包含import語句,那麽應該放在package語句和類定義之間。
- 如果沒有package語句,那麽import語句應該在源文件中最前面。
- import語句和package語句對源文件中定義的所有類都有效。
- 在同一源文件中,不能給不同的類不同的包聲明。
- 類有若幹種訪問級別,並且類也分不同的類型:抽象類和final類等。這些將在訪問控制章節介紹。
- 除了上面提到的幾種類型,Java還有一些特殊的類,如:內部類、匿名類。
3. 包Package
為了更好地組織類,Java 提供了包機制,用於區別類名的命名空間。
3.1 包的作用
- 把功能相似或相關的類或接口組織在同一個包中,方便類的查找和使用。
- 如同文件夾一樣,包也采用了樹形目錄的存儲方式。同一個包中的類名字是不同的,不同的包中的類的名字是可以相同的,當同時調用兩個不同包中相同類名的類時,應該加上包名加以區別。因此,包可以避免名字沖突。
- 包也限定了訪問權限,擁有包訪問權限的類才能訪問某個包中的類。
Java 使用包(package)這種機制是為了防止命名沖突,訪問控制,提供搜索和定位類(class)、接口、枚舉(enumerations)和註釋(annotation)等。
包語句的語法格式為:
package pkg1[.pkg2[.pkg3…]];
例如,一個Something.java 文件它的內容
package net.java.util
public class Something{
...
}
那麽它的路徑應該是 net/java/util/Something.java 這樣保存的。 package(包) 的作用是把不同的 java 程序分類保存,更方便的被其他 java 程序調用。
一個包(package)可以定義為一組相互聯系的類型(類、接口、枚舉和註釋),為這些類型提供訪問保護和命名空間管理的功能。
以下是一些 Java 中的包:
java.lang-打包基礎的類
java.io-包含輸入輸出功能的函數
開發者可以自己把一組類和接口等打包,並定義自己的包。而且在實際開發中這樣做是值得提倡的,當你自己完成類的實現之後,將相關的類分組,可以讓其他的編程者更容易地確定哪些類、接口、枚舉和註釋等是相關的。
由於包創建了新的命名空間(namespace),所以不會跟其他包中的任何名字產生命名沖突。使用包這種機制,更容易實現訪問控制,並且讓定位相關類更加簡單。
3.2 創建包
創建包的時候,你需要為這個包取一個合適的名字。之後,如果其他的一個源文件包含了這個包提供的類、接口、枚舉或者註釋類型的時候,都必須將這個包的聲明放在這個源文件的開頭。
包聲明應該在源文件的第一行,每個源文件只能有一個包聲明,這個文件中的每個類型都應用於它。
如果一個源文件中沒有使用包聲明,那麽其中的類,函數,枚舉,註釋等將被放在一個無名的包(unnamed package)中。
3.3 import關鍵字
為了能夠使用某一個包的成員,我們需要在 Java 程序中明確導入該包。使用 "import" 語句可完成此功能。
在 java 源文件中 import 語句應位於 package 語句之後,所有類的定義之前,可以沒有,也可以有多條,其語法格式為:
import package1[.package2…].(classname|*);
如果在一個包中,一個類想要使用本包中的另一個類,那麽該包名可以省略。
例子: 下面的 payroll 包已經包含了 Employee 類,接下來向 payroll 包中添加一個 Boss 類。Boss 類引用 Employee 類的時候可以不用使用 payroll 前綴,Boss類的實例如下。
package payroll;
public class Boss
{
public void payEmployee(Employee e)
{
e.mailCheck();
}
}
如果 Boss 類不在 payroll 包中又會怎樣?Boss 類必須使用下面幾種方法之一來引用其他包中的類。
- 使用類全名描述,例如:
payroll.Employee
- 用 import 關鍵字引入,使用通配符 "*",例如:
import payroll.*;
- 使用 import 關鍵字引入 Employee 類:
import payroll.Employee;
註意: 類文件中可以包含任意數量的 import 聲明。import 聲明必須在包聲明之後,類聲明之前。
3.4 package的目錄結構
類放在包中會有兩種主要的結果:
- 包名成為類名的一部分,正如我們前面討論的一樣。
- 包名必須與相應的字節碼所在的目錄結構相吻合。
下面是管理你自己 java 中文件的一種簡單方式:
-
將類、接口等類型的源碼放在一個文本中,這個文件的名字就是這個類型的名字,並以.java作為擴展名。例如:
// 文件名 : Car.java package vehicle; public class Car { // 類實現 }
-
接下來,把源文件放在一個目錄中,這個目錄要對應類所在包的名字。
....\vehicle\Car.java
-
現在,正確的類名和路徑將會是如下樣子:
類名 -> vehicle.Car 路徑名 -> vehicle\Car.java (在 windows 系統中)
通常,一個公司使用它互聯網域名的顛倒形式來作為它的包名.例如:互聯網域名是 rimi.com,所有的包名都以 com.rimi 開頭。包名中的每一個部分對應一個子目錄。
例如:有一個 com.rimi.test 的包,這個包包含一個叫做 JavaBasic.java 的源文件,那麽相應的,應該有如下面的一連串子目錄:
....\com\rimi\test\JavaBasic.java
編譯的時候,編譯器為包中定義的每個類、接口等類型各創建一個不同的輸出文件,輸出文件的名字就是這個類型的名字,並加上 .class 作為擴展後綴。 例如:
// 文件名: JavaBasic.java
package com.rimi.test;
public class JavaBasic {
}
class Google {
}
現在,我們用-d選項來編譯這個文件,如下:
$javac -d . JavaBasic.java
這樣會像下面這樣放置編譯了的文件:
.\com\rimi\test\JavaBasic.class
.\com\rimi\test\Google.class
你可以像下面這樣來導入所有 \com\rimi\test\ 中定義的類、接口等:
import com.runoob.test.*;
編譯之後的 .class 文件應該和 .java 源文件一樣,它們放置的目錄應該跟包的名字對應起來。但是,並不要求 .class 文件的路徑跟相應的 .java 的路徑一樣。你可以分開來安排源碼和類的目錄。
<path-one>\sources\com\rimi\test\JavaBasic.java
<path-two>\classes\com\rimi\test\Google.class
這樣,你可以將你的類目錄分享給其他的編程人員,而不用透露自己的源碼。用這種方法管理源碼和類文件可以讓編譯器和java 虛擬機(JVM)可以找到你程序中使用的所有類型。
類目錄的絕對路徑叫做 class path。設置在系統變量 CLASSPATH 中。編譯器和 java 虛擬機通過將 package 名字加到 class path 後來構造 .class 文件的路徑。
<path- two>\classes 是 class path,package 名字是 com.rimi.test,而編譯器和 JVM 會在 <path-two>\classes\com\rimi\test 中找 .class 文件。
一個 class path 可能會包含好幾個路徑,多路徑應該用分隔符分開。默認情況下,編譯器和 JVM 查找當前目錄。JAR 文件按包含 Java 平臺相關的類,所以他們的目錄默認放在了 class path 中。
3.5 設置CLASSPATH系統變量
用下面的命令顯示當前的CLASSPATH變量:
- Windows 平臺(DOS 命令行下):C:> set CLASSPATH
- UNIX 平臺(Bourne shell 下):# echo $CLASSPATH
刪除當前CLASSPATH變量內容:
- Windows 平臺(DOS 命令行下):C:> set CLASSPATH=
- UNIX 平臺(Bourne shell 下):# unset CLASSPATH; export CLASSPATH
設置CLASSPATH變量:
- Windows 平臺(DOS 命令行下): C:> set CLASSPATH=C:\users\jack\java\classes
- UNIX 平臺(Bourne shell 下):# CLASSPATH=/home/jack/java/classes; export CLASSPATH
10. 內部類、源文件規則和包