一、多態
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代碼塊處理,並打印異常信息。