Java基礎--多態、Object類、內部類、異常


一、多態

   1.概念

        同一個對象,在程序不同時刻的多種運行狀態。

        多態在代碼中的體現:父類或者接口的引用指向其子類的對象。

   2.多態的前提

        a.存在着繼承或者實現關係

        b.有方法的重寫

    3.多態的好處和弊端

         好處:多態的存在提高了程序的擴展性和後期可維護性

         弊端:雖然可以預先使用,但是隻能訪問父類中已有的功能,運行的是後期子類的功能內容。

    4.多態中對象調用成員的特點

         Fu f = new Zi();

         A:成員變量:編譯看左邊,運行看左邊

         B:成員方法: 編譯看左邊,運行看右邊

         C:靜態方法:編譯看左邊,運行看左邊

    5.多態的思想
         指揮同一批對象做事情。

     6.多態的應用

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

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

         c.操作同一父類型,對其中的子類型均可操作        

     程序示例:

abstract class Person{  //定義抽象類Person
	abstract void sleep();//定義抽象方法sleep
}
//定義Student類並繼承Person
class Student extends Person{
	public void sleep(){
		System.out.println("學生在睡覺");
	}
	public void study(){
		System.out.println("學生在學習");
	}
}
//定義Worker類並繼承Person
class Worker extends Person{
	public void sleep(){
		System.out.println("工人在睡覺");
	}
	public void work(){
		System.out.println("工人在工作");
	}
}
public class DuoTai {

	public static void main(String[] args) { 
       method(new Student()); //調用method方法,並將創建的Student實例對象作爲參數傳入
       method(new Worker());  //調用method方法,並將創建的Worker實例對象作爲參數傳入
	}
	public static void method(Person p) {
		p.sleep();
		if(p instanceof Student){
			Student s=(Student)p;//將Person對象強轉爲Student類型
			s.study();
		}
		else if(p instanceof Worker){
			Worker w=(Worker)p;  //將Person對象強轉爲Worker類型
			w.work();
		}
	}
}

運行結果:


二、Object類

     1.概念

         所有類的根類,超類。java中提供的類以及我們自定義的類都直接或者間接的繼承自Object類。

     2.Object類中的方法

         A:void finalize()

            當垃圾回收器確定不存在對該對象的更多引用時,由對象的垃圾回收器調用此方法。

         B:Class getClass()

            獲取對象的字節碼文件的描述類,後面再講反射的時候還會在說這個類。

            String name = s.getClass().getName();

         C:int hashCode()

            獲取對象的哈希值。其實就是對象的內存地址值十進制表示

         D:String toString()

            返回對象的字符串表示。

            表示格式: getClass().getName()+"@"+Integer.toHexString(hashCode());

            一般我們輸出對象名的時候,其實底層調用的就是該對象的toString()方法。

         E:boolean  equals(Object obj)

             用於比較兩個對象的地址值是否相同

       3.==和equals的用法

         A:==怎麼用?

            a.可以用於比較基本數據類型,比較的就是基本數據類型的值是否相等。

            b.可以用於比較引用數據類型,比較的是對象的地址值是否相等。

        B:equals怎麼用?

           equals只能用於比較引用數據類型的。

           a.Object提供的equals是用於比較對象地址值是否相同。

           b.自定義類中,如果重寫了equals方法,那麼就是按照你自己的需求來比較的。


三、內部類

     1.把一個類定義在某個類中的,這個類就被稱爲內部類,內置類,嵌套類。根據內部類的位置、修飾符和定義的方式可分爲成員內部類、靜態內部類、方法內部類。

     2.訪問特點:內部類可以直接訪問外部類中的成員,因爲內部類持有外部類的引用, 格式爲:外部類名.this;外部類要想訪問內部類的成員,必須創建對象訪問。

     3.內部類的訪問格式:

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

            格式:外部類名.內部類名  變量名 = new 外部類對象.內部類對象

            例:Outer.Innerin = new Outer().new Inner();

         B:當內部類在外部類成員位置,且被static修飾時,外部其他類可直接訪問靜態內部類的非靜態成員。

            格式:new 外部類名.內部類名().內部類成員

            例:newOuter.Inner().function();

      4.什麼使用時候內部類?

         假如有A類和B類,A類想直接訪問B類的成員,B類訪問A類成員的時候,需要創建A類對象進行訪問,這個時候,就可以把A類定義爲B類的內部類。  

       程序示例:      

class Outer{
	private int num=3;
	//定義一個成員方法,方法中訪問內部類
	public void test(){
		Inner inner=new Inner();
		inner.show();
	}
	//定義一個成員內部類
	class Inner{
		void show(){
			System.out.println("num="+num);
		}
	}
}
public class Test2 {

	public static void main(String[] args) {
    Outer outer=new Outer();     //創建外部類對象
    outer.test();               //調用test()方法
	}
}
       程序解析:程序運行結果爲num=3;Outer類是一個外部類,在該類中定義了一個內部類Inner和一個test()方法,Inner類有一個show()方法,在show()方法中訪問外部類的成員變量num,test()方法中創建了內部類Inner實例對象,並通過該對象調用show()方法,將num值進行打印。

      5.匿名內部類

          (1)匿名內部類就是局部內部類的簡寫。

          (2)前提:繼承一個類或者實現一個接口。

          (3)格式:

                 new父類名或者接口名()

                   {

                       重寫父類方法或者實現接口中的方法。

                       也可以自定義其他方法。

                    };

          (4)什麼時候定義匿名內部類?

               匿名內部類只是爲了簡化書寫,匿名內部類有侷限,通常定義匿名內部類時,該類方法不超過3個。

          (5)匿名內部類的好處和弊端:

               好處:簡化代碼書寫。

               弊端: 不能直接調用自己的特有方法,不能執行強轉換動作,  如果該類裏面方法較多,不允許使用匿名內部類。

 四、異常

        1.程序運行過程中的不正常現象就叫異常。

       2.導致程序運行不正常的現象有很多,所以,就有很多的異常對象。 而這些異常對象存在着共性的內容,所以,可以不斷的進行抽取。最終形成了異常的體系結構。

           異常體系的根類是:Throwable

               |--Error:重大的問題,我們處理不了。也不需要編寫代碼處理。比如說內存溢出。

               |--Exception:一般性的錯誤,是需要我們編寫代碼進行處理的。

                  |--RuntimeException:運行時異常,這個我們也不需要處理。其實就是爲了讓他在運行時出問題,然後我們回來修改代碼。                         

       3.異常的分類     

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

            運行時異常(編譯時不檢測):在編譯時,不需要處理,編譯器不檢查。 該異常的發生,建議不處理,讓程序停止。需要對代碼進行修正。         

      4.異常體系的特點

            異常體系中的所有類及其子類對象都具備可拋性。也就是說可以被throw和throws關鍵字所操作。

      5.Throwable類

           getMessage():獲取異常信息,返回字符串。

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

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

       6.異常的處理

                   try...catch...finally

                   基本格式:

                            try

                            {

                                   可能出現異常的代碼

                            }

                            catch(異常對象)

                            {       

                                     異常處理代碼

                            }

                            finally

                            {

                                     釋放資源

                            }

       注意事項:1.多個異常同時被捕獲的時候,記住一個原則: 先逮小的,再逮大的。

                         2.finally:永遠被執行,除非退出jvm。System.exit(0);          

       7.異常常見的問題

          a.final,finally,finalize區別。

           final是最終的意思。它可以用於修飾類,成員變量,成員方法。它修飾的類不能被繼承,它修飾的變量時常量,它修飾的方法不能被重寫。

           finally:是異常處理裏面的關鍵字。它其中的代碼永遠被執行。特殊情況:在執行它之前jvm退出。System.exit(0);

           finalize:是Object類中的一個方法。 它是於垃圾回收器調用的方式。        

         b.main方法是如何處理異常的?       

            1).在main裏面編寫代碼進行處理

            2).交給jvm自己進行處理。採用的是jvm的默認處理方式。其實就是相當於調用了異常對象的printStackTrace()方法。        

      8.自定義異常

           定義類繼承Exception或者RuntimeException

            a.爲了讓該自定義類具備可拋性。

            b.讓該類具備操作異常的共性方法。

             1)繼承Exception的自定義異常             

class classMyExcepiton extends Exception
{
     MyExcepiton(){
        super();//調用Exception無參的構造方法
      }  
     MyExcepiton(String message)
    {
       super(message);//調用Exception有參的構造方法
     }
 }

             2)繼承RuntimeException的自定義異常            

class classMyExcepiton extends RuntimeException
{
     MyExcepiton(){
        super();//RuntimeException無參的構造方法
      }  
     MyExcepiton(String message)
    {
       super(message);//調用RuntimeException有參的構造方法
     }
 }

       9.throws和throw的區別

          a. 有throws的時候可以沒有throw。 有throw的時候,如果throw拋的異常是Exception體系,那麼必須有throws在方法上聲明。

         b.throws用於方法的聲明上,其後跟的是異常類名,後面可以跟多個異常類,之間用逗號隔開,throw用於方法體中,其後跟的是一個異常對象名。

           程序示例:

//自定義一個異常類
class DivideByMinusException extends Exception{
	public DivideByMinusException(String msg){
	  super(msg);
	}
}
public class test1 {

	public static void main(String[] args) {
		try{
			//調用divide()方法,傳入除數與被除數
	       int result=divide(6,-2);
		   System.out.println(result);
		   }
		catch(DivideByMinusException e){
		  System.out.println(e.getMessage());//打印捕獲的異常
		}
	}	
	public static int divide(int x, int y) throws DivideByMinusException  {
	  if(y<0){
		  //使用throw關鍵字聲明異常對象
		throw new DivideByMinusException("被除數是負數");
		 }
		int result=x/y; //定義一個變量result記錄兩個數相除的結果
	    return result;  //將結果返回
	}
}

          程序解析:程序最終運行結果爲:被除數爲負數。main()方法中,定義了一個  try...catch語句用於捕獲divide()方法拋出的異常。在調用divide()方法時由於傳入的被除數不能爲負數,程序會拋出一個自定義異常,該異常被捕獲後最終被catch代碼塊處理,並打印異常信息。

                   


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