1. 程式人生 > >Java的一些小知識:package,import,不同目錄下類的呼叫

Java的一些小知識:package,import,不同目錄下類的呼叫

這道題一共要建三個目錄:C:\myproj\bin、C:\myproj\lib和C:\myproj\classes,也可以自己建所要的目錄,三個目錄不同就可以了,具體要求如下:

n public的A.class和B.class屬於包X.Y,該包存放在C:\myproj\classes中;public的C.class和D.class屬於包S.T,把它們打包為E.jar檔案中,並存放在C:\myproj\lib中;這些類均有四個方法:public void sayPublic()、private void sayPrivate()、protected void sayProtected()、void sayDefault(),而且都只包含一條語句System.out.println("Hi,"+getClass()+"."+函式許可權(public|private|protected|default))。

n Test1.class、Test2.class和Test3.class為測試類(帶入口函式),存放在目錄C:\myproj\bin下。

n 打包命令:jar  cvf  K.jar  *  (注意把子目錄S/T也一起打包進去)。

 (吐槽下,做實驗報告模板的老師或者TA這裡對這道題的表述有些混亂 == 至少我是這樣感覺的)

實驗步驟:

(1) Test1分別建立A和C的一個物件並呼叫這四個方法,看看哪些方法可以使用,不能使用的就註釋掉。

     Test1執行截圖:

    

Test1的原始碼:

/*因為A.class和C.class不在Test1.java的所在目錄中,所以需要引用包進來,
 * 自動新增classpath在前之後,表示包位於
 * H:\web\實驗\java實驗\lab3\code\classes\X\Y 
 * 或
 * H:\web\實驗\java實驗\lab3\code\lib\S\T
 * 下*/

import X.Y.*; 
import S.T.*;

public class Test1{
  public static void main(String[] args){
	  A a = new A();
	  	a.sayPublic();
	  	//a.sayPrivate();
	  	//a.sayProtected();
	  	//a.sayDefault();
	  C c = new C();
	  	c.sayPublic();
	  	//c.sayPrivate();
	  	//c.sayProtected();
	  	//c.sayDefault();
  }
}


(2)Test2繼承B並直接呼叫它的四個方法,看看哪些方法可以使用,不能使用的就註釋掉。
* 在main()中要採用“Test2 test2=new Test2(); test2.sayPublic();”進行呼叫,直接呼叫會出現 “無法從靜態上下文中引用非靜態方法”的錯誤(因為要呼叫非靜態方法,必須先要建立物件)

     Test2執行截圖:

     

Test2的原始碼:

/*因為B.class不在Test1.java的所在目錄中,所以需要引用包進來,
 * 自動新增classpath在前之後,表示包位於
 * H:\web\實驗\java實驗\lab3\code\classes\X\Y 
 * 下*/

import X.Y.*; 
//import S.T.*;

public class Test2 extends B{
  public static void main(String[] args){
	  Test2 test2 = new Test2();
	  	test2.sayPublic();
	  	test2.sayProtected();
	  	//下面兩個無法引用(編譯時報錯)
	  	//test2.sayPrivate();
	  	//test2.sayDefault();
  }
}

(3)Test3繼承D並直接呼叫它的四個方法,看看哪些方法可以使用,不能使用的就註釋掉。

     Test3執行截圖:


     Test3的原始碼:

/*因為D.class不在Test1.java的所在目錄中,所以需要引用包進來,
 * 自動新增classpath在前之後,表示包位於
 * H:\web\實驗\java實驗\lab3\code\lib\S\T
 * 下*/

//import X.Y.*; 
import S.T.*;

public class Test3 extends D{
  public static void main(String[] args){
	  Test3 test3 = new Test3();
	  	test3.sayPublic();
	  	test3.sayProtected();
	  	//同樣下面兩個無法引用(編譯時報錯)
	  	//test3.sayPrivate();
	  	//test3.sayDefault();
  }
}


(4)A~D類的源程式。

      A的源程式:

/*用package語句指明所屬包的名稱,
 * 相當於註釋語句,只是告訴人說這些.java或.class在這個子目錄下*/
package X.Y;

public class A
{
	public void sayPublic()
	{
		System.out.println("Hi,"+getClass()+ "."+ "public");
	}
	
	private void sayPrivate()
	{
		System.out.println("Hi,"+getClass()+ "."+ "private");
	}
	
	protected void sayProtected()
	{
		System.out.println("Hi,"+getClass()+ "."+ "protected");
	}
	
	void sayDefault()
	{
		System.out.println("Hi,"+getClass()+ "."+ "default");
	}
}

 B的源程式:

/*用package語句指明所屬包的名稱,
 * 相當於註釋語句,只是告訴人說這些.java或.class在這個子目錄下*/
package X.Y;

public class B
{
	public void sayPublic()
	{
		System.out.println("Hi,"+getClass()+ "."+ "public");
	}
	
	private void sayPrivate()
	{
		System.out.println("Hi,"+getClass()+ "."+ "private");
	}
	
	protected void sayProtected()
	{
		System.out.println("Hi,"+getClass()+ "."+ "protected");
	}
	
	void sayDefault()
	{
		System.out.println("Hi,"+getClass()+ "."+ "default");
	}
}


 C的源程式:

/*用package語句指明所屬包的名稱,
 * 相當於註釋語句,只是告訴人說這些.java或.class在這個子目錄下*/
package S.T;

public class C
{
	public void sayPublic()
	{
		System.out.println("Hi,"+getClass()+ "."+ "public");
	}
	
	private void sayPrivate()
	{
		System.out.println("Hi,"+getClass()+ "."+ "private");
	}
	
	protected void sayProtected()
	{
		System.out.println("Hi,"+getClass()+ "."+ "protected");
	}
	
	void sayDefault()
	{
		System.out.println("Hi,"+getClass()+ "."+ "default");
	}
}

D的源程式:

/*用package語句指明所屬包的名稱,
 * 相當於註釋語句,只是告訴人說這些.java或.class在這個子目錄下*/
package S.T;

public class D
{
	public void sayPublic()
	{
		System.out.println("Hi,"+getClass()+ "."+ "public");
	}
	
	private void sayPrivate()
	{
		System.out.println("Hi,"+getClass()+ "."+ "private");
	}
	
	protected void sayProtected()
	{
		System.out.println("Hi,"+getClass()+ "."+ "protected");
	}
	
	void sayDefault()
	{
		System.out.println("Hi,"+getClass()+ "."+ "default");
	}
}


通過上面的實驗,你可以得到什麼結論:

結論是對於一個類(如A),如果不是在同一個包中,那其他的類(如Test1)如果不是A的子類,那麼類Test1只能訪問A的public修飾的方法,如果Test1是A的子類,那麼它可以訪問A的public和protected修飾的方法。也就是老師PPT上列出的:


       由於時間比較緊,因為現在已經快12點了,得趕著睡覺然後明天早起寫公選的讀書報告了,所以對於這次實驗就不在這裡寫詳細的解析了,這裡只複製下自己在做實驗過程彙總整理的一些word筆記,通過這些筆記也基本可以搞清楚這次實驗的相關知識和一些難點了:

1:這樣編譯C.java才能根據package語句自動新建子目錄並在子目錄生成.class檔案(得先進入到lib資料夾路徑裡才有效),兩種方法都行,第一種方法的”.”表示當前目錄:


其他的A.java B.java D.java也是同樣的方法。不用這種方法的話就無法根據package語句自動新建子目錄並在子目錄生成.class檔案,而要自己新建目錄並把.class檔案剪下到該目錄。

2:打包jar檔案首先cd到lib資料夾再輸入報告裡面那句程式碼(”jar cvf  E.jar  *”):

3:一定要把C.java和C.class檔案都放在子目錄下,然後再生成jar包(對於A.java B.jaba不用壓縮),然後再編譯Test1.java才能通過。不然報下面這樣的錯誤,為啥?

4:編譯Test1.java:先cd到bin目錄(即Test1.java所在目錄),再javac,同時中間要加上引用的A類和B類的包的路徑(最後的”;.”中的”.”表示把當前目錄也就是bin目錄也作為classpath納入進來,雖然並沒有用到這個目錄的.class檔案)


(這裡的截圖是把privated protected default的呼叫註釋掉了之後的,沒註釋掉的應該是下面的截圖,會報錯)

5:執行Test1.class: 同樣要加入classpath: