黑馬程式設計師——Java基礎---內部類與異常
第二講 內部類與異常
一、內部類
1、內部類:將一個類定義在另一個類的裡面,對裡面那個類就稱為內部類(內建類,巢狀類)。
2、內部類訪問特點:
(1)內部類可以直接訪問外部類的成員,包括私有成員原因:之所以可以直接訪問外部類中的成員,是因為內部類中 持有了一
個外部類的引用,格式 外部類名.this。
(2)而外部類要訪問內部類中的成員必須要建立內部類的物件。
3、 訪問格式
(1)當內部類在外部類的成員位置上,而且非私有,可以在外部其他類中,直接建立內部類物件。
格式:外部類名.內部類名 變數名=外部類物件.內部類物件;
Outer.Inter in = new Outer( ).new Inner( );
(2)當內部類在外部類成員位置上,就可以被成員修飾符所修飾,比如:private :將內部類在外部類中進行封裝。
static:內部類就具備了static的特性。當內部類被static修飾,只能直接訪問外部類中的static成員出現了訪問侷限。
<1> 在外部其他類中,如何直接訪問static內部類的非靜態成員呢?
new Outer.Inner().function( );
<2>在外部其他類中,如何直接訪問static內部類的靜態成員呢?
Outer.Inner.function( );
注意:當內部類中定義類靜態成員,該內部類必須是static的,當外部類中的static方法訪問內部類時,內部類也必須是static
的。區域性內部類是不可以被static修飾的。當描述事物時,事物的內部還有事物,該事物用內部類來描述,因為內部事物在使用外部
事物的內容(變數和函式)。
<span style="font-size:18px;">class Body
{
private class Heart()
{
}
public void show()
{
new Heart;
}
}</span>
內部類定義在區域性時<1>不可以被成員修飾符(static)修飾
<2>可以直接訪問外部類中的成員,因為還持有外部類的引用。但是不可以訪問它所在的區域性中的變數,只能訪問被final 修飾
的區域性變數。內部類可以被私有修飾,當內部類在外部類的成員位置上時就可以,外部類不可以被私有。
程式示例
<span style="font-size:18px;">class Outer
{
private int x=3;
class Inner //內部類
{
<span style="white-space:pre"> </span>void function()
{
System.out.println("inner:"+x);
}
}
void method()
{
Inner in=new Inner();
in.function();
}
}
class InnerClassDemo
{
public static void main(String[] args)
{
Outer out=new Outer();
out.method();
//直接訪問內部類中的成員
Outer.Inter in=new Outer().new Inner();
in.function();
}
}</span>
匿名內部類:<1>匿名內部類其實就是內部類的簡寫格式。
<2>定義內部類的前提:內部類必須繼承一個類或者實現介面。
<3>匿名內部類的格式:new 父類或者介面(){定義子類的內容}。
<4>其實內部匿名類就是一個匿名子類物件。而且這個物件有點胖,可以理解為帶內容的物件。
<5>匿名內部類中定義的方法最好不超過3個。匿名物件只對物件方法呼叫一次。
<span style="font-size:18px;">abstract class AbsDemo
{
abstract void show();
}
class Outer
{
int x=3;
class Inner extends AbsDemo
{
void show()
{
System.out.println("show :"+x);
}
void abc()
{
System.out.println("abc:"+x);
}
}
public void function()
{
<span style="white-space: pre;"> </span>new Inner().show();
<span style="white-space: pre;"> </span>AbsDemo a=new Inner();
AbsDemo d=new AbsDemo()
{
void show()
{
System.out.println("x="+x);
}
void abc()
{
System.out.println("abc:"+x);
}
};
d.show();
//d.abc();//編譯失敗,
}
}
class InnerClassDemo4
{
public static void main(String[] args)
{
new Outer().function();
}
}</span><span style="font-size: 14px;">
</span>
二、異常
1、異常: 程式執行時出現的不正常情況
2、異常的由來:問題也是現實生活中一個具體的事物,也可以通過java的類的形式進行描述,並封裝成物件 ,其實就java
對不正常情況進行描述後的物件體現。對於問題的劃分:兩種:一種是嚴重的問題,一種是非嚴重的問題對於嚴重的,java通Error
類進行描述。 一般不編寫針對性的程式碼對其處理。對於非嚴重的,java通過Exception類進行描述。可以使用針對性的處理方式進行
描述。異常的體系無論Exception還是Error都具有一些共性內容。比如,不正常情況的資訊,引發原因等。
Throwable
|--Error
|--Exception
Exception和Error的子類名都是以父類作為字尾。異常的處理java提供了特有的語句進行處理。
<span style="font-size:18px;">try
{
需要被檢測的程式碼
}
catch(異常類 變數)
{
處理異常的程式碼(處理方式)
}
finally
{
一定會執行的語句;
}</span>
(1)對捕獲到的異常物件進行常見方法操作:
<1>String getMessage():獲取異常資訊。
<2>toString():異常名稱,異常資訊。
<3>printStackTrace():異常名稱,異常資訊,異常位置。其實JVM預設的處理異常機制就是在呼叫 printStackTrace
方法列印異常在堆疊的跟蹤資訊。
(2)對多異常的處理。
<1>宣告異常時,建議宣告更為具體的異常,這樣處理的可以更具體。
<2>如果宣告幾個異常就對應幾個catch塊,不要定義多餘的catch塊。如果多個catch塊中的異常出現繼承關係
父類異常catch塊放在最下面,建議在進行catch處理時,catch中一定要定義具體處理方式,
不要簡單一句e.printStackTrace(),也不要簡單的就寫一條輸出語句。因為專案中會出現特有的問題;而這些問題並沒
有被java所描述並封裝物件所以對於這些特有的問題可以按照java的對問題封裝思想,將特有問題進行自定義的異常
封裝。因為項目中會出現特有的問題;而這些問題並沒有被java所描述並封裝物件所以對於這些特有的問題可以按照
java的對問題封裝思想,將特有問題進行自定義的異常封裝。
自定義異常;
(3)必須是自定義類繼承Exception.
繼承Exception原因:異常體系有一個特點:因為異常類和異常物件都被丟擲,他們都具備可拋性,這個可拋性
是Throwable這個體系中獨有的特點,只有這個體系的類和物件才可以被throws和throw操作。
throws和throw的區別
<1>throws使用在函式上,throw使用在函式內。
<2>throws後面跟的異常類,可以跟多個,用逗號隔開,throw後跟的是異常物件。
Exception中有一個特殊的子類異常RuntimeException執行時異常如果在函式內丟擲該異常,函式上可以不用聲
明,編譯一樣通過如果在函式上聲明瞭該異常,呼叫者可以不用進行處理,編譯一樣通過;之所以不用在函式上聲
明,是因為不需要讓呼叫者處理,當異常發生,希望程式停止,因為在執行時,出現了無法繼續運算的情況,希望停
止程式後,由程式設計師對程式碼進行修正。
自定義異常時:如果該異常的發生,無法再繼續進行運算,就讓自定義異常繼承RuntimeException。
對於異常分兩種:
<1>編譯時被檢測的異常.
<2>編譯時不被檢測的異常(執行時異常,RuntimeException以及其子類).
程式示例
<span style="font-size:18px;">class FuShuException extends Exception //getMessage();
{
private int value;
FuShuException()
{
super();
}
FuShuException(String msg,int value)
{
super(msg);
this.value=value;
}
public int getValue()
{
return value;
}
}
class Dem
{
int div(int a,int b)throws FuShuException//在功能上通過throws的關鍵字聲明瞭該功能有可能會出現問題。
{
if(b<0)
throw new FuShuException("出現了除數是負數的情況/by FuShu",b);/*手動通過throw關鍵字丟擲一個自定義異常物件<span style="font-family: Arial, Helvetica, sans-serif;">*/ </span><span style="font-family: Arial, Helvetica, sans-serif;">/*if(b==0)</span></span>
<span style="font-size:18px;"> throw new ArithmeticException("被0除了");*/
return a/b;
}
}
class ExceptionDemo
{
public static void main(String[] args)
{
Dem d =new Dem();
try
{
int x=d.div(4,1);
System.out.println("x="+x);
}
catch (FuShuException e)
{
System.out.println(e.toString());
System.out.println("除數出現負數了");
System.out.println("錯誤的資訊是"+e.getValue());
}
System.out.println("over");
}
}</span>