封裝性是指對外部的封裝

 子類不能訪問基類實例本身的受保護成員:

 

main方法中創建另一個類的對象,然後調用其方法

 

1、課程名稱:包及訪問控制權限
 包的定義及使用、常用包介紹、JAR命令、訪問控制權限、命名要求
2、知識點
2.1、上次課程的主要知識點
 1、 異常的產生及處理流程
 2、 throw和throws關鍵字的作用
2.2、本次預計講解的知識點
 1、 包的定義及使用
 2、 系統常用包
 3、 JAR命令
 4、 訪問控制權限
3、具體內容
3.1、包的定義及使用
3.1.1、包的定義
 所謂的包就是一個文件夾,因爲在多人開發中爲了避免命名重複的問題發生,所以引入了包的概念。通過不同的包可以保存同名的類。
3.1.2、包的操作
 在一個*.java文件之中使用package就可以定義個包了。
 在包的命名中,所有的單詞要採用小寫的形式。
 語法如下:
package 包名稱.子包名稱.子包名稱 ;
例如:以下的程序使用了包的定義
package org.lxh ;
public class Hello{
 public static void main(String args[]){
  System.out.println("Hello World!!!") ;
 }
};
 與之前打印“Hello World”不同的是,此處類定義在了包中,也就是說,如果一個類定義了一個包,那麼類的訪問全名:包.類名稱。
 在JAVA中提供了專門打包指令,可以根據定義的package生成所要的文件夾。
 javac -d . Hello.java
  • “-d”:表示的是生成目錄,根據package的定義生成
  • “.”:表示在當前所在的文件夾之中生成
 則以後,如果要是再想訪問此類的話,輸入的類名稱爲:org.lxh.Hello
 既然可以在程序中定義一個包,那麼程序就可以導入若干包,導入的語法如下:
import 包.類名稱 ;
例如:以下的程序自己定義了一個包的類,同時進行訪問
• 定義Hello.java的類。
package org.lxh.demo1 ;
class Hello{
 public void print(){
  System.out.println("Hello World!!!") ;
 }
};
 • 定義Demo的類,此類導入上面的包.類名稱:
package org.lxh.demo1 ;
public class Demo{
 public static void main(String args[]){
  new Hello().print() ;
 }
};
 以上的類並沒有導包,因爲在同一個文件夾之中。發現以上代碼跟之前沒太大的差別。
 那麼下面將Demo所在的包定義成:org.lxh.demo2,與Hello不在同一個包中。
Demo.java:
package org.lxh.demo2 ;
import org.lxh.demo1.Hello ;
public class Demo{
 public static void main(String args[]){
  new Hello().print() ;
 }
};
 出現了以下的錯誤信息:
Demo.java:2: org.lxh.demo1.Hello 在 org.lxh.demo1 中不是公共的;無法從外部軟件包中對其進行訪問
import org.lxh.demo1.Hello ;
                     ^
Demo.java:5: 找不到符號
符號: 類 Hello
位置: 類 org.lxh.demo2.Demo
                new Hello().print() ;
                    ^
2 錯誤
 問題的原因,說Hello不是公共的,所以不能訪問,也就是說默認的訪問權限可以在同一個包中訪問,但是不能讓所有的不同包的用戶訪問。
 聲明public class和class的區別:
• 使用public class聲明則類名稱必須與文件名稱一致,如果一個類想被外包所訪問,則此類一定要聲明成publli class
• 使用class聲明的類可以與文件名稱不一致,此類只能在本包中訪問。
 所以,以上的程序,應該把Hello的定義修改爲:public class Hello。
Hello.java:
package org.lxh.demo1 ;
public class Hello{
 public void print(){
  System.out.println("Hello World!!!") ;
 }
};
 在之前的程序之中,可以發現導入的時候導入的是一個具體的類名稱,如果在一個包下有很多的類呢?則要一個個導入嗎?明顯很複雜,所以在JAVA中可以使用通配符“*”表示導入所需要的類。
修改Demo.java:
package org.lxh.demo2 ;
import org.lxh.demo1.* ;
public class Demo{
 public static void main(String args[]){
  new Hello().print() ;
 }
};
疑問:
 如果一個個的導入包,是不是會比使用“*”性能要高呢?
• 從JAVA中的類的加載來看,程序中使用了“*”,那麼對於JVM來說不會將一個包下的所有類全部導入,而只導入自己所需要的類,不需要的根本不會使用上,所以一各個導入與寫“*”,在性能上是完全一樣的。
 另外,因爲在JAVA中會存在類名稱相同的情況,所以,以後一旦出現了類名稱相同的情況,則可以使用完整的包.類名稱的方式聲明一個類的對象。
例如:修改Demo.java
package org.lxh.demo2 ;
public class Demo{
 public static void main(String args[]){
  org.lxh.demo1.Hello h = new org.lxh.demo1.Hello() ;
  h.print() ;
 }
};
 以上爲標準的操作語法,也是在一般的開發中使用較多的語法。
注意:
 所有的類必定放在一個包中,沒有包的類是不存在。
3.1.3、靜態導包指令(瞭解)
 在JDK 1.5之後,JAVA提供了靜態導入的操作,可以將一個類中的全部靜態方法導入進來直接使用。
例如:以下的一個類定義了若干個靜態方法
package org.lxh.d1 ;
public class Print{
 public static void printHello(){
  System.out.println("Hello") ;
 }
 public static void printWorld(){
  System.out.println("World") ;
 }
};
 此類中本身提供了兩個靜態方法。
編寫一個Test類,使用以下的語法導入:
import static 包.類.*
例如:驗證以上語法
package org.lxh.d2 ;
import static org.lxh.d1.Print.* ;
public class Test{
 public static void main(String args[]){
  printHello() ;  //  靜態方法
  printWorld() ;  //  靜態方法
 }
};
 但是,一般正常情況下,此特性是沒人使的。
3.1.4、系統常用包
 在JAVA中的JDK裏本身已經爲用戶提供了很多的開發包,掌握這些開發包的時候可以方便的實現各種功能,一些常見的包如下所示:
No. 包名稱 作用
1 java.lang 此包爲基本的包,像String、Integer這樣的類就都保存在此包之中,在JDK 1.0的時候如果想編寫程序,則必須手工導入此包,但是JDK 1.1之後解決了此問題,所以此包現在爲自動導入
2 java.lang.reflect 此包爲反射機制的包,是java.lang的子包
3 java.util 此包爲工具包,一些常用的類庫、日期操作等等都在此包之中,如果把此包掌握精通各種設計思路都好理解
4 java.text 提供了一些文本的處理類庫
5 java.sql 數據庫操作包,提供了各種數據庫操作的類和接口
6 java.net 完成網絡編程的包
7 java.io 輸入、輸出處理類
 其中以java.util、java.io包是最麻煩的。而且也是最重要的
3.2、JAR命令
 一般情況下,用戶開發完成的包,都會交給其他用戶去使用,如果給的時候往往不可能把一堆的*.class文件給這些用戶,而是將這些CLASS文件打成一個壓縮包的形式。
 直接在屏幕上輸入jar就可以查看到jar的使用命令語法。
 
 主要參數:
  • c:創建新的存檔
  • v:生成詳細輸出到標準輸出上
  • f:指定存檔文件名
例如:現在有以下的一個類:
HelloDemo.java:
package org.lxh ;
public class HelloDemo{
 public void print(){
  System.out.println("Hello World!!!") ;
 }
};
 之後對此程序進行打包編譯:javac -d . HelloDemo.java
 輸入:jar -cvf my.jar org,將org目錄打包成JAR文件,文件名稱爲:my.jar。
 一個*.jar文件之中包含了META-INF纔可以使用。
此時,編寫一個測試程序,使用此*.jar包
package org.lxh.demo ;
import org.lxh.* ;
public class TestDemo{
 public static void main(String args[]){
  new HelloDemo().print() ;
 }
};
 編譯TestDemo.java類。出現以下的錯誤提示:
TestDemo.java:5: 找不到符號
符號: 類 HelloDemo
位置: 類 org.lxh.demo.TestDemo
                new HelloDemo().print() ;
                    ^
1 錯誤
 找不到HelloDemo的類。所以,如果此時,想要訪問的話,則必須設置classpath。但是一般情況下classpath設置在當前目錄中是較爲常見的,所以此時的設置classpath的語法如下:
set classpath=.;E:\javademo\oo8\my.jar
 通過“;”區分出不同的classpath路徑,就可以訪問了,也就是說,只要是*.jar包則一定要配置classpath之後纔可以使用。
3.3、訪問控制權限
在JAVA中提供了四種訪問權限:
 • private(私有):只有同一個類可以訪問
 • default(默認):在同一個包下都可以訪問
 • protected(受保護):同一個包下和不同包的子類可以訪問
 • public(公共):所有的都可以訪問
範圍 private default protected public
同一類中的成員 √ √ √ √
同一包中的成員 × √ √ √
不同包中的子類 × × √ √
不同包中的非子類 × × × √
例如:以下代碼驗證protected訪問權限
1、 建立一個PHello.java的類。
package org.lxh1 ;
public class PHello{
 protected String info = "HELLO" ;
};
2、 建立一個不同包的類,裏面有一個子類。
package org.lxh2 ;
import org.lxh1.* ;
class D extends PHello{
 public void print(){
  System.out.println(super.info) ;
 }
};
public class PDemo{
 public static void main(String args[]){
  D h = new D() ;
  h.print() ;
 }
};
 以上的代碼可以在子類中訪問受保護成員。但是如果現在在不同包的非子類中訪問,則出現以下的錯誤:
package org.lxh3 ;
import org.lxh1.* ;
public class PTest{
 public static void main(String args[]){
  PHello p = new PHello() ;
  p.info = "HELLO" ;   不是子類
 }
};
 錯誤提示:
PTest.java:6: info 可以在 org.lxh1.PHello 中訪問 protected
                p.info = "HELLO" ;
                 ^
1 錯誤
3.4、命名要求
 只要是JAVA的開發中所有的命名都必須按照此要求編寫:
  • 類:所有單詞的首字母大寫
  • 方法:第一個單詞的首字母小寫,之後每個單詞的首字母大寫
  • 屬性:第一個單詞的首字母小寫,之後每個單詞的首字母大寫
  • 包:所有單詞的字母小寫
  • 常量:所有單詞的字母大寫
4、總結
1、 包可以爲類的開發提供方便,可以解決同名類所帶來的問題
2、 可以使用package定義一個包,之後使用import在需要的地方導入包
3、 JDK中提供了很多常用的系統功能包,例如:java.util包
4、 JAR命令可以把開發的包打成一個文件,之後交給其他用戶使用
5、 JAVA分爲四種訪問控制權限:private<default<protected<public
5、面向對象總結
面向對象三大特徵:
 • 封裝性:是爲了讓類中的內容對外不不可見,但是後來發現如果一個類要訪問封裝的屬性則封裝屬性所在的類必須提供getter和setter方法,不方便,所以產生了內部類,因爲通過內部類可以方便的訪問出外部類的私有屬性,但是內部類本身會破壞代碼的結構。
 • 爲了保證整體代碼的結構,引入了繼承的特性,實際上所謂的封裝性是指對外部的封裝。所以在類的聲明中可以使用protected聲明,因爲使用protected聲明可以直接讓子類訪問。那麼這樣一來。就好象內部類可以訪問外部類中的私有屬性,解決了私有屬性訪問的問題,同時又保證了程序代碼的結構性。
 • 產生繼承之後,發現如果一個類的子類過多了,則在操作的時候就很麻煩,所以使用對象的多態性,一切的操作標準以父類爲標準,這樣的話可以減少很多代碼。
 • 在JAVA中因爲類與類之間的繼承有單繼承的侷限,有的時候並不能通過單繼承解決全部的問題,所以引入了接口的概念,一個類可以實現多個接口。
 • 接口的多實現性逐步成爲一個操作的標準,所以有了嚴格的規定,一個類不要去繼承一個已經實現好的類,而應該只繼承抽象類或實現接口。
 • 在開發不可避免的會出現類名稱的重複性,所以使用了包的概念。
 • 對於所有的操作代碼,因爲其可能會出現問題,所以要把所有的錯誤交給被調用處處理。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章