黑馬程序員——面向對象(多態,內部類、異常、包)

------- android培訓java培訓、期待與您交流! ----------

第一講     多態

一、多態的概念     

        多態可以理解爲事物存在的多種體現形態。

        例:動物中貓,狗。貓這個對象對應的類型是貓類型,如:貓 x = new(); 同時貓也是動物中的一種,也可以把貓稱爲動物。動物  y = new(); 那麼動物就是貓和狗具體事物中抽取出來的父類型。父類型引用指向了子類對象。

 

二、多態的體現

       1、父類的引用指向了自己子類的對象。 

        2、父類的引用也可以接收自己的子類對象。

如:   Animal a = new Cat();

        其中就將父類型的 a 引用指向了子類的對象。

 

三、多態的前提

       1、類與類之間必須有關係,要麼繼承,要麼實現。

        2、存在覆蓋。父類中有方法被子類重寫。

 

四、多態的利與弊

        利:提高了程序的可擴展性和後期可以維護性。

        弊:只能使用父類中的引用訪問父類中的成員。也就是說使用了多態,父類型的引用在使用功能時,不能直接調用子類中的特有方法。如:Animal a = new Cat(); 這代碼就是多態的體現,假設子類Cat中有特有的抓老鼠功能,父類型的 a就不能直接調用。這上面的代碼中,可以理解爲Cat類型提升了,向上轉型。

        如果此時父類的引用想要調用Cat中特有的方法,就需要強制將父類的引用,轉成子類類型,向下轉型。如:Catc = (Cat)a;

注:如果父類可以創建對象,如:Animal a = new Animal(); 此時,就不能向下轉型了,Cat c = (Cat)a; 這樣的代碼就變得不容許,編譯時會報錯。所以千萬不能出現這樣的操作,就是將父類對象轉成子類類型。

        我們能轉換的是父類引用指向了自己的子類對象時,該引用可以被提升,也可以被強制轉換。多態至始至終都是子類對象在做着變化。

下面就是一個多態的示例:

[java] view plaincopy
  1. //父類————動物  
  2. abstract class Animal  
  3. {  
  4.     public abstract void eat();  
  5.   
  6. }  
  7.   
  8. //子類————貓  
  9. class Cat extends Animal  
  10. {  
  11.     //複寫父類中的抽象功能  
  12.     public void eat()  
  13.     {  
  14.         System.out.println("吃魚");  
  15.     }  
  16.   
  17.     //Cat特有的功能  
  18.     public static void catchMouse()  
  19.     {  
  20.         System.out.println("抓老鼠");  
  21.     }  
  22. }  
  23.   
  24.   
  25. class Demo  
  26. {  
  27.     public static void main(String[] args)   
  28.     {  
  29.         Animal a = new Cat();  
  30.         a.eat();  
  31.         Cat c = (Cat)a;  
  32.         c.catchMouse();  
  33.     }  
  34. }  

結果:

 

五、多態的特點

1、多態中非靜態成員函數的特點

        在編譯時期:參閱引用型變量所屬的類中是否有調用的方法。如果有,編譯通過,如果沒有編譯失敗。

如:在上面的示例中,如果用a.catchMouse();編譯就會報錯。這時只能通過強轉,向下轉型後,可以使用子類的特有功能。

        在運行時期:參閱對象所屬的類中是否有調用的方法。這就是說,如果父類中有一個非抽象的方法,而子類繼承後又將其複寫了,在多態運行時,父類的引用調用這個同名函數時,被運行的將是父類中的方法。

        簡單總結就是:成員函數在多態調用時,編譯看左邊,運行看右邊。

2、多態中成員變量的特點

        無論編譯和運行,都參考左邊(引用變量所屬的類)。如:多態中的父類引用調用成員變量時,如果父類和子類有同名的成員變量,那麼被調用的是父類中的成員變量。

3、多態中靜態成員函數的特點

        無論編譯和運行,都參考左邊。也就是父類引用在調用靜態同名函數時,被調用的是父類中的靜態函數。這是因爲,當類一被加載,靜態函數就隨類綁定在了內存中。此時,不需要創建對象,就可以使用類名直接調用。同時,父類中的靜態成員函數一般是不被複寫的。

類在方法區中的分配:分爲靜態區和非靜態區,而關鍵字thissuper在非靜態區。

 

六、多態的應用

        1、定義好工具類,即將共同行爲封裝在一個類中。

        2、對類型進行抽取,---->多態的產生。

        3、操作同一父類型,對其中的子類型均可操作

實例小程序:

[java] view plaincopy
  1. /* 
  2. 電腦的運行實例。電腦的運行由主板控制,假設主板只是提供電腦運行,但是沒有上網,聽歌等功能。而上網、聽歌需要硬件的支持。而現在主板上沒有網卡和聲卡,這時可以定義一個規則,叫PCI,只要符合這個規則的網卡和聲卡都可以在主板上使用,這樣就降低了主板和網卡、聲卡之間的耦合性。用程序體現。 
  3. */  
  4. // 接口PCI  
  5. interface PCI  
  6. {  
  7.     void open();  
  8.     void close();  
  9. }  
  10.   
  11. //網卡實現接口  
  12. class NetCard implements PCI  
  13. {  
  14.     public void open()  
  15.     {  
  16.         System.out.println("NetCard_open");  
  17.     }  
  18.       
  19.     public void close()  
  20.     {  
  21.         System.out.println("NetCard_close");  
  22.     }  
  23. }  
  24.   
  25. //聲卡實現接口  
  26. class SoundCard implements PCI  
  27. {  
  28.     public void open()  
  29.     {  
  30.         System.out.println("SoundCard_open");  
  31.     }  
  32.   
  33.     public void close()  
  34.     {  
  35.         System.out.println("SoundCard_close");  
  36.     }  
  37. }  
  38.   
  39. class Mainboard  
  40. {  
  41.     //電腦運行  
  42.     public static void run()  
  43.     {  
  44.         System.out.println("Mainboard_run");  
  45.     }  
  46.       
  47.     //使用擴展功能  
  48.     public static void usePCI(PCI p)//PCI p = new NetCard()//接口型引用指向自己的子類對象。  
  49.     {  
  50.         if(!(p==null))  
  51.         {  
  52.             p.open();  
  53.             p.close();  
  54.         }  
  55.     }  
  56. }  
  57.   
  58. class Demo  
  59. {  
  60.     public static void main(String[] args)   
  61.     {  
  62.         Mainboard m =new Mainboard();  
  63.         //電腦運行  
  64.         m.run();  
  65.           
  66.         //  m.usePCI(null);  
  67.   
  68.         //電腦上網  
  69.         m.usePCI(new NetCard());  
  70.   
  71.         //電腦聽歌  
  72.         m.usePCI(new SoundCard());  
  73.     }  
  74. }  

結果:

 

第二講     內部類

一、概述

        將一個類定義在另一個類的裏面,對裏面那個類就稱爲內部類(內置類,嵌套類)。

        當描述事物時,事物的內部還有事物,該事物用內部類來描述。因爲內部事物在使用外部事物的內容。如定義一個描述人的類,而手、心臟等都屬於人,然它們又有自己的功能描述,這時可以在人這個描述類中,定義一個描述心臟的類,也就是內部類。

        編譯時,如果代碼中有內部類,生成的class文件中會含有這樣的文件:Test$1.class。編譯器將會把內部類翻譯成用$(美元符號)分隔外部類名和內部類名的常規類文件。這是內部類的一種編譯現象。

 

二、內部類的訪問規則

        1、內部類可以直接訪問外部類中的成員,包括私有。

              之所以可以直接訪問外部類中的成員,是因爲內部類中持有了一個外部類的引用,格式:  外部類名.this

        2、外部類要訪問內部類,必須建立內部類對象。

 

三、訪問格式

1、當內部類定義在外部類的成員位置上,而且非私有,可以在外部其他類中。可以直接建立內部類對象。

        格式:

                 外部類名.內部類名  變量名 =外部類對象.內部類對象;

        如:    Outer.Inner in =new Outer().new Inner();

當內部類在外部類中的成員位置上時,可以被成員修飾符所修飾。比如:

        private:將內部類在外部類中進行封裝。 

        static:內部類就局部static的特性。但是當內部類被static修飾後,只能直接訪問外部類中的static成員。出現了訪問侷限。

在外部其他類中,直接訪問static內部類的非靜態成員的格式爲:

        new 外部類名.內部類名().方法名();

        如:new  Outer.Inner().function();

在外部其他類中,直接訪問static內部類的靜態成員格式爲:

        外部類名.內部類名.方法名();

        如:Outer.Inner.function();

注意:

        1)當內部類中定義了靜態成員時,該內部類必須是static的。

        2)當外部類中的靜態方法訪問內部類時,內部類也必須是static的。

        3)在實際應用中,內部類通常被定義爲private,而很少定義爲public

2、內部類定義在局部

        內部類定義在外部類中的某個方法中,創建了這個類型的對象時,且僅使用了一次,那麼可在這個方法中定義局部類。

        1)不可以被成員修飾符修飾。如publicprivatestatic等修飾符修飾。它的作用域被限定在了聲明這個局部類的代碼塊中

        2)可以直接訪問外部類中的成員,因爲還持有外部類中的引用。

注意:內部類不可以訪問它所在的局部中非最終變量。只能訪問被final修飾的局部變量。

如下面的代碼:

[java] view plaincopy
  1. class Outer  
  2. {  
  3.     int x = 3;  
  4.     void method(final int a)  
  5.     {  
  6.         final int y = 4;  
  7.         //局部內部類  
  8.                 class Inner  
  9.         {  
  10.             void function()  
  11.             {  
  12.                 System.out.println(y);  
  13.             }  
  14.         }  
  15.         new Inner().function();//使用局部內部類中的方法。  
  16.     }  
  17. }  
  18. class  InnerClassDemo  
  19. {  
  20.     public static void main(String[] args)   
  21.     {  
  22.         Outer out = new Outer();  
  23.         out.method(7);//打印7  
  24.         out.method(8);//打印8  
  25.     }  
  26. }  

注:爲什麼上面的代碼中打印的值爲什麼會改變呢?被final修飾的變量的值是不會被改變的。這裏類調用方法使用完後,這時這個被final修飾的變量已經從棧內存中消失了,類再次調用這個方法時,已經是另一變量,所以可以重新被傳值。

 

四、匿名內部類

        1、匿名內部類其實就是內部類的簡寫格式。

        2、定義匿名內部類的前提:

              內部類必須是繼承一個類或者實現接口。

              特殊情況:因爲所以的類都有一個父類Object,所以在定義時也可以用Object

        3、匿名內部類的格式:  new父類或者接口(){定義子類的內容}

        4、其實匿名內部類就是一個匿名子類對象。可以理解爲帶內容的對象。

        5、匿名內部類中定義的方法最好不要超過3個。

匿名內部類的利與弊:

        好處:簡化書寫

        弊端:1、不能直接調用自己的特有方法、

                     2、不能做強轉動作。

                     3、如果繼承的父類或接口中有很多方法時,使用匿名內部類閱讀性會非常差,且調用會很麻煩。所以匿名內部類中定義的方法有一般不超過3個。

匿名內部類的應用:

[java] view plaincopy
  1. interface Inter  
  2. {  
  3.     void method();  
  4. }  
  5. class InnerClassTest   
  6. {  
  7.     public static void main(String[] args)   
  8.     {  
  9.         show(new Inter()  
  10.         {  
  11.             public void method()  
  12.             {  
  13.                 System.out.println("method show run");  
  14.             }  
  15.         });  
  16.     }  
  17.   
  18.     public static void show(Inter in)  
  19.     {  
  20.         in.method();  
  21.     }  
  22. }  


 小練習:

題目:

[java] view plaincopy
  1. interface Inter  
  2. {     
  3.     void method();  
  4. }  
  5.       
  6. class Test  
  7. {  
  8.     //補足代碼,通過匿名內部類  
  9. }  
  10. class InnerClassDemo   
  11. {  
  12.     public static void main(String[] args)   
  13.     {  
  14.             Test.function().method();     
  15. }  
  16.     }  

分析:

       Test.function().method();//相當於Inter in=Test.function();in.method();

                                              //Test.function():Test類中有一個靜態的方法function

                                             //.method():function這個方法運算後的結果是一個對象。而且是一個Inter類型的對象

                                            //因爲只有是Inter類型的對象,纔可以調用method方法。

完整代碼爲:

[java] view plaincopy
  1. interface Inter  
  2. {     
  3.     void method();  
  4. }  
  5.   
  6. class Test  
  7. {  
  8.     //補足代碼,通過匿名內部類  
  9.     static Inter function()  
  10.     {     
  11.         return new Inter()  
  12.         {  
  13.             public void method()  
  14.             {  
  15.                 System.out.println("內部類練習");  
  16.             }  
  17.         };  
  18.     }  
  19. }  
  20.   
  21. class InnerClassDemo   
  22. {  
  23.     public static void main(String[] args)   
  24.     {  
  25.         Test.function().method();  
  26.     }  
  27. }  

輸出結果:

       

第三講    異常

        異常是Java中的重要機制,也使用了面向對象的思想,進行了封裝。我們通常使用的異常類。而異常類中所描述的就是程序中可能出現的錯誤或者問題。就像人生病一樣,不一定經常有,但總有生病的時候,而且生病的原因不同,性質不同,對其的治療自然也不一樣。這些都可以在異常類中得以展現。

 

一、概述

        1、異常:就是程序在運行時出現不正常情況。

        2、異常由來:問題也是現實生活中一個具體的事物,也可以通過java的類的形式進行描述。並封裝成對象。其實就是java對不正常情況進行描述後的對象體現。

        3、程序可能出現的錯誤或問題

                a、用戶輸入錯誤導致的異常:如用戶不正常使用程序,輸入一些非法參數

                b、設備硬件等發生的錯誤:如硬盤損壞等

                c、物理限制:如存儲空間不足等

                d、代碼錯誤:在程序編寫的方法可能不正確,返回錯誤參數等。

 

二、異常體系

        有兩種對問題的劃分方式:

               一種是嚴重的問題;

              一種是非嚴重的問題。

         對於嚴重的問題,java通過Error類進行描述。對Error類一般不編寫針對性的代碼對其進行處理。

        對於非嚴重的,java通過Exception類進行描述。對於Exception可以使用針對性的處理方式進行處理。

         無論Error或者Exception都具有一些共性內容。比如:不正常情況的信息,引發原因等。

這也就構成了Java的異常體系:

        Throwable

                |---Error  //通常出現重大問題如:運行的類不存在或者內存溢出等。

                |---Exception //運行時出現的一起情況

                            |---R       untimeException    //特殊異常類,拋時不需要聲明

        ExceptionError的子類名都是以父類名作爲後綴。

異常體系的特點:

        1、異常體系中的所有類以及建立的對象都具備可拋性。

         2、也就是說可以被throwthrows關鍵字所操作。

        3、只有異常體系具備這個特點。

 

三、異常有兩種:

        1、編譯時被檢測異常

              該異常在編譯時,如果沒有處理(沒有拋也沒有try),編譯失敗。該異常被標識,代表着可以被處理。

         2、運行時異常(編譯時不檢測)

               在編譯時,不需要處理,編譯器不檢查。該異常的發生,建議不處理,讓程序停止。需要對代碼進行修正。如:RuntimeException以及其子類。

 

四、異常的處理

1 java提供了特有的語句進行處理。

        try

        {

                 需要被檢測的代碼。

        }

        catch(異常類  變量)

        {

                 處理異常的代碼;(處理方式)

        }

        finally

        {

                 一定會執行的語句;

        }

有三個結合格式:

        atry

             {

             }

             catch ()

             {

             }

        btry

             {

             }

             finally

             {

             } 

        ctry

             {

             }

             catch ()

             {

             }

             finally

             {

             } 

注意:

        1finally中定義的通常是關閉資源代碼。因爲資源必須釋放。

        2)如果在一個功能中,定義了一些必須要執行的代碼,可以用try{}finally{}的方式,將一定執行的代碼放在finally代碼塊中。

        3finally只有一種情況不會執行。當執行到System.exit(0);fianlly不會執行。

2throwthrows的用法

        throw定義在函數內,用於拋出異常對象。

        throws定義在函數上,用於拋出異常類,可以拋出多個用逗號隔開。

        當函數內容有throw拋出異常對象,並未進行try處理。必須要在函數上聲明,否則編譯失敗。

        注意:RuntimeException除外。也就說,函數內如果拋出的RuntimeExcpetion異常,函數上可以不用聲明。

3、調用者對拋出信息的處理

        當在函數內部出現了throw拋出異常對象,那麼就必須要給對應的處理動作。要麼在內部try catch處理。要麼在函數上聲明讓調用者處理。

        一般情況下,函數內出現異常,函數上需要聲明。在功能上通過throws的關鍵字聲明瞭該功能有可能會出現異常類型。

特殊之處:

        Exception中有一個特殊的子類異常RuntimeException 運行時異常。

                1 如果在函數內拋出該異常,函數上可以不用聲明,編譯一樣通過。

                2)如果在函數上聲明瞭該異常。調用者可以不用進行處理。編譯一樣通過。

        之所以不用在函數上聲明,是因爲不需要讓調用者處理。當該異常發生,希望程序停止。因爲在運行時,出現了無法繼續運算的情況,希望停止程序後,對代碼進行修正。

         如果函數聲明瞭異常,調用者需要進行處理。處理方法可以throws可以try

對捕獲到的異常對象進行常見方法操作:

        String getMessage();//獲取異常的信息。返回字符串。

        toString();//獲取異常類名和異常信息,返回字符串。

        printStackTrace();//獲取異常類名和異常信息,以及異常出現在程序中的位置.返回值void.

                                //其實JVM默認的異常處理機制,就是在調用printStackTrace方法,打印異常的堆棧的跟蹤信息。

        printStackTrace(PrintStream s)//通常用該方法將異常內容保存在日誌文件中,以便查閱。

 

五、自定義異常

        因爲項目中會出現特有的問題,而這些問題並未被java所描述並封裝對象。所以對這些特有的問題可以按照java中的面向對象思想。將特有的問題,進行自定義的異常封裝。定義類繼承Exception或者RuntimeException

        1,爲了讓該自定義類具備可拋性。

        2,讓該類具備操作異常的共性方法。

這就叫做自定義異常。

        當自定義了異常類繼承Exception後,如果未在類中定義異常信息,那麼通過toString方法打印出來的結果就只有自定義的異常類名,不會顯示異常信息。那麼應該如何定義異常信息呢?

        要定義自定義異常的信息時,可以使用父類已經定義好的功能。異常信息傳遞給父類的構造函數。因爲父類中已經把異常信息的操作都完成了。所以子類只要在構造時,將異常信息傳遞給父類通過super語句。那麼就可以直接通過getMessage方法獲取自定義的異常信息。

        如:

[java] view plaincopy
  1. class ZiDingYiException extends Exception  
  2. {  
  3.     private String msg;  
  4.     ZiDingYiException(String msg)  
  5.     {  
  6.         super(msg);//將會返回輸入的信息  
  7.      }  
  8. }  

自定義異常時:如果該異常的發生,無法再繼續進行運算,就讓自定義異常繼承RuntimeException

注:自定義異常:

                必須是自定義類有繼承關係,通常繼承Exception

         繼承Exception原因:

                 異常體系有一個特點:因爲異常類和異常對象都被拋出。他們都具備可拋性。這個可拋性是Throwable這個體系中獨有特點。

                 只有這個體系中的類和對象纔可以被throwsthrow操作。

 

六、異常的好處與原則

好處:

        1、將問題進行封裝。

        2、將正常流程代碼和問題處理代碼相分離,方便於閱讀。

原則:

        1、處理方式有兩種:try或者 throws

        2、調用到拋出異常的功能時,拋出幾個,就處理幾個。一個try對應多個catch

        3、多個catch時,父類的catch放到最下面。否則編譯會報錯,因爲其餘的catch語句執行不到。

        4catch內,需要定義針對性的處理方式。不要簡單的定義printStackTrace,輸出語句。也不要不寫。當捕獲到的異常,本功能處理不了時,可以繼續在catch中拋出。

      如:   

[java] view plaincopy
  1. try  
  2. {  
  3.     throw new AException();  
  4. }  
  5. catch (AException e)  
  6. {  
  7.     throw e;  
  8. }  

        如果該異常處理不了,但並不屬於該功能出現的異常。可以將異常轉換後,在拋出和該功能相關的異常。

        或者異常可以處理,當需要將異常產生後和本功能相關的問題提供出去,讓調用者知道。並處理。也可以將捕獲異常處理後,轉換新的異常。這樣就好比在給別人轉賬時,如果ATM機出現故障,這時可以另外找地方去轉,也可以告訴對方,轉賬不成功。

      代碼例:  

[java] view plaincopy
  1. try  
  2. {  
  3.          throw new AException();  
  4. }  
  5. catch (AException e)  
  6. {  
  7.          // 對AException處理。  
  8.          throw new BException();  
  9. }  

 

七、異常的注意事項

        1、問題在內部被解決就不需要聲明。

        2catch是用於處理異常。如果沒有catch就代表異常沒有被處理,如果該異常是檢測時異常。那麼必須聲明。

        3、在子父類覆蓋時:

              a,子類拋出的異常必須是父類的異常的子類或者子集。

              b,如果父類或者接口沒有異常拋出時,子類覆蓋出現異常,只能try不能拋。

如:

[java] view plaincopy
  1. class AException extends Exception  
  2. {  
  3. }  
  4.   
  5. class BException extends AException  
  6. {  
  7. }  
  8.   
  9. class CException extends Exception  
  10. {  
  11. }  
  12.   
  13. /*上面代碼的繼承關係 
  14. Exception  
  15.     |--AException 
  16.         |--BException 
  17.     |--CException 
  18. */  
  19. class Fu  
  20. {  
  21.     void show()throws AException  
  22.     {  
  23.     }  
  24. }  
  25.   
  26. class Test  
  27. {  
  28.     void function(Fu f)  
  29.     {  
  30.         try  
  31.         {  
  32.             f.show();  
  33.         }  
  34.         catch (AException e)  
  35.         {  
  36.         }  
  37.     }  
  38. }  
  39.   
  40. class Zi extends Fu  
  41. {  
  42.     void show()throws CException  
  43.     {  
  44.         //如果這裏子類拋出CException,父類中的catch就無法處理,  
  45.         //這樣就會導致編譯失敗,所以子類只能繼承父類中的異常或子集  
  46.     }  
  47. }  

異常的小練習:      

[java] view plaincopy
  1. /* 
  2. 老師使用電腦講課。 
  3.  
  4. 描述電腦: 
  5.     1、電腦運行 
  6.     2、電腦重啓 
  7. 描述電腦問題: 
  8.     1、電腦藍屏了 
  9.     2、電腦起火了 
  10.  
  11. 描述老師: 
  12.     1、老師使用電腦 
  13.     2、老師講課。 
  14. 描述老師可能出現的問題: 
  15.     1、老師不能繼續講課了,他讓同學們自己做練習。 
  16.  
  17. */  
  18.   
  19. //電腦藍屏了  
  20. class BlueScreenException extends Exception  
  21. {  
  22.     BlueScreenException(String message)  
  23.     {  
  24.         super(message);  
  25.     }  
  26. }  
  27. //電腦起火了  
  28. class FireBreakingException extends Exception  
  29. {     
  30.     FireBreakingException(String message)  
  31.     {  
  32.         super(message);  
  33.     }  
  34. }  
  35.   
  36. //老師無法繼續上課  
  37. class StopTeachException extends Exception  
  38. {     
  39.     StopTeachException(String message)  
  40.     {  
  41.         super(message);  
  42.     }  
  43. }  
  44. class Computer  
  45. {  
  46.     int start=1;  
  47.     //電腦啓動  
  48.     void run()throws BlueScreenException,FireBreakingException  
  49.     {  
  50.         if(start==2)  
  51.             throw new BlueScreenException("Computer_BlueScreen");  
  52.         else if(start==3)  
  53.             throw new FireBreakingException("Computer_FireBreaking");  
  54.         System.out.println("Computer_run");  
  55.     }  
  56.     //電腦重啓  
  57.     void reset()  
  58.     {     
  59.         start=1;  
  60.         System.out.println("Computer_reset");  
  61.     }  
  62. }  
  63.   
  64. class Teacher  
  65. {  
  66.     private String name;  
  67.     private Computer cpt;  
  68.   
  69.     //對老師進行初始化  
  70.     Teacher(String name)  
  71.     {  
  72.         this.name=name;  
  73.         cpt=new Computer();  
  74.     }  
  75.   
  76.     //老師開始講課  
  77.     public void teach()throws StopTeachException  
  78.     {  
  79.         try  
  80.         {  
  81.             cpt.run();  
  82.               
  83.         }  
  84.         catch (BlueScreenException e)  
  85.         {  
  86.             //System.out.println(e.getMessage());  
  87.             cpt.reset();  
  88.         }  
  89.         catch (FireBreakingException e)  
  90.         {  
  91.             test();  
  92.             //System.out.println(e.getMessage());  
  93.             throw new StopTeachException("Teather_StopTeach:"+e.getMessage());  
  94.         }  
  95.   
  96.         System.out.println(name+"Teacher_teaching");  
  97.     }  
  98.     void test()  
  99.     {  
  100.         System.out.println("學生做練習");  
  101.     }  
  102.   
  103. }  
  104. class ExceptionTest  
  105. {  
  106.     public static void main(String[] args)   
  107.     {  
  108.         Teacher t=new Teacher("畢老師");  
  109.         try  
  110.         {  
  111.             t.teach();  
  112.         }  
  113.         catch (StopTeachException e)  
  114.         {  
  115.             System.out.println(e.toString());  
  116.             System.out.println("換老師或者放假");  
  117.         }  
  118.     }  
  119. }  

當電腦藍屏時,結果爲:

       

當電腦起火時,結果爲:

       

 

第四講     

一、package

        在java中,管叫包,相當於文件夾。包裏通常存放的是類文件,因爲我們在編寫程序的時候,難免會有類名相同的情況,就如我們人名一樣。爲了對類進行分類管理,java就有了包的出現,在不同包中可以有相同的類名,調用的時候連同包名一起就行。

        包也是一種封裝形式。在包中可以有很多類文件,但是隻提供一個類文件,供外界使用。

 

二、包的作用

        1、爲避免多個類重名的情況,如果出現兩個相同名字的類,可通過包將兩者區分,從而避免衝突。

        2、對類文件進行分類管理,可以將相關的一些類放在同一個包中。

        3、給類提供多層命名空間,如a包中的Demo.class文件,如果要創建Demo對象,就要在使用時加上a.如:a.Demo demo=new a.Demo();

        4、包的出現可以將java的類文件和源文件相分離。

 

三、規則      

        1、包必須寫在程序的第一行。因爲要先有包,才知道類文件的存放地方。

        2、類的全稱:包名.類名。

        3、編譯定義了包的程序文件時,在編譯時要指定包的存儲目錄。

       如:javac –d c:\mypack類名.java

 

四、包之間的訪問      

        1、要訪問其他包中的類,需要定義類的全稱:包名.類名。

        2、包如果不在當前路徑,需要使用classpath設定環境變量,爲JVM指明路徑。

        3、被訪問的包中的類權限必須是public的。

        4、類中的成員權限:public或者protectedprotected是爲其他包中的子類提供的一種權限。類公有後,被訪問的成員也要公有纔可以被訪問。不同包中的子類可以直接訪問父類中被protected權限修飾的成員。同一個包中,protected只作用爲覆蓋。

四種權限

 

public

protected

defauld

Private

同一類中

可以

可以

可以

可以

同一包中

可以

可以

可以

不可以

子類

可以

可以

不可以

不可以

不同包中

可以

不可以

不可以

不可以

注:一個.java文件裏面,不能出現兩個以上的公有類或者接口。因爲被public修飾的類名必須與java文件名相同。

 

五、包的導入——import

        1、可以簡化類名。在調用其他包中的類時,需要寫類的全稱,也就是連同包名一起書寫。當類存在多層包中時,如:haha.hehe.pack.Demo,使用import導入後,使用其類時,就可以不加包名了。導入格式如:import haha.hehe.pack.Demo;

        2、一個程序文件中只有一個package,可以有多個importimport導入的是包中的類,不導入包中的包。

        3、注意事項:

               a,在導入包時,如果包中有很多類,可以使用通配符 *來替代包中的所有類。但是,建議不要使用通配符 * ,因爲將不需要使用的類導入後,會佔用內存空間。所有在編寫程序時,要使用包中的哪些類,就導入哪些類。

               b,定義包名不要重複,可以使用url來完成定義,url是唯一的。如:package cn.itheima.Demo

               c,導入的不同包中有相同類時,必須寫類的全名以區分,否則將會報錯。

 

六、jar

        類越來越多,我們可以用包來裝,當包越來越多時,我們可以將包進行壓縮。而java中用jar這個工具來對包進行壓縮。壓縮後的後綴名爲jar

jar.exe工具的一些命令:

        創建jar

                jar  -cvf  mypack.jar packa packb

        查看jar

                jar  -tvf  mypack.jar  [>定向文件]

        解壓縮

                jar  -xvf  mypack.jar

        自定義jar包的清單文件

                jar cvfm  mypack.jar mf.txt  packa packb

jar包的好處:

        1、 可以將多個包進行壓縮到爲一個文件。方便項目的攜帶。

        2、 方便於使用,只要在classpath設置jar路徑,即可以執行jar包中的java程序。

        3、 數據庫驅動,SSH框架等都是以jar包體現的。

小練習:

Demo類程序:

[java] view plaincopy
  1. package packab;//創建包packab  
  2. public class  Demo  
  3. {  
  4.     public void show()  
  5.     {  
  6.         System.out.println("Demo show");  
  7.         System.out.println("Hello World!");  
  8.     }  
  9. }  

PackDemo類程序:

[java] view plaincopy
  1. package pack;//創建pack包  
  2. import packab.Demo;//導入類Demo  
  3. public class  PackageDemo  
  4. {  
  5.     public static void main(String[] args)   
  6.     {  
  7.         new Demo().show();//使用pack包中類Demo的方法  
  8.     }  
  9. }  

結果:

       

在目錄下生產的包:

       

 生成jar包命令:

       

目錄中:

將兩包刪除,只剩下jar包。dos命令行指定classpath,然後輸出的結果:

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