Java之內部類與異常類
一、內部類
在一個類中定義另一個類,這樣的類成為內部類,包含內部類的類稱為 內部類的 外嵌類。
內部類與外嵌類的關係:
1.內部類可以呼叫其外嵌類的方法和成員變數
2.內部類中不可以宣告類變數和類方法
3.外嵌類可以 用內部類宣告的物件 ,作為外嵌類的成員。
4.內部類僅供其對應的外嵌類使用,其他類不可以宣告別的類的內部類物件。
public class RCF{
static String from;
//內部類的宣告
class RedCow{
String cown = "red";
int h , w;
RedCow(int H,int W){
h = H; w = W;
}
void speak(){
System.out.println("Name:" + cown +"; Height:" + h
+ "; Weight:" + w + "; Family:" + from);
}
}
RedCow cow;//內部類宣告物件
RCF(String s){
cow = new RedCow(152,100);
from = s;
}
public void show(){
cow.speak();
}
}
public class neibulei {
public static void main(String[] args) {
RCF rcf = new RCF("andy");
rcf.show();
rcf.cow.speak();
// RCF.RedCow rc = new RCF.RedCow(180, 150);
// rc.speak();
}}
還記得static嗎?類成員和類變數,在這裡,內部類也可以被修飾為static內部類,即外嵌類中的一種靜態資料型別,用static修飾後,就可以在其他類中使用static內部類來建立物件
二、匿名類
匿名類,什麼是匿名類?沒有名字的類啊,那沒有名字的類怎麼來用呢?沒有名字肯定就不能宣告物件呀,但是卻可以直接建立物件的。那不能宣告物件,怎麼用這個匿名類呢? 那就作為引數來用呀!
匿名類有兩種,一種是與子類有關,一種是與介面有關
其實匿名類就是直接建立物件的啊,無論是與子類有關還是與介面有關,他都是沒有類名直接建立的。你看現在若有一個A類,那麼我們是如何建立他的物件的? A a = new A(); 這樣,就建立了一個A類的物件a,那現在我們是如何建立匿名類呢? 直接寫 new A{ 匿名類類體 }; 這不就是直接建立了一個類嗎,這也就可以理解了匿名類是一個子類吧。也因為匿名類沒有名字可以用來宣告,所以常常直接建立一個匿名類物件 引數。
1.和子類有關的匿名類
匿名類的特點:
1.匿名類可以繼承和重寫父類的方法(匿名類就是一個子類)。
2.匿名類一定是內部類,因為他一定是在某個類中直接用匿名來建立物件的。
3.匿名類可以訪問外嵌類中的成員變數和方法,但是匿名類中不可以宣告static成員變數和static方法。
//抽象類物件
abstract class OutputAlphabet {
public abstract void output();
}
//OutputAlphabet類的一個子類
public class OutputEnglish extends OutputAlphabet{
public void output() {
for(char c = 'a';c <= 'h';c++){
System.out.printf("%3c",c);
}
}
}
public class ShowBoard {
void showMess(OutputAlphabet show){ //引數是OutputAlphabet型別的物件
show.output();
}
}
public class nimig {
public static void main(String[] args) {
ShowBoard board = new ShowBoard();//引數是一個OutputEnglish型別的物件,對於一個引數直接是一個物件我是有點不太理解的,他是怎麼用的呢?看下面,應該會容易理解一點
board.showMess(new OutputEnglish());//引數直接為物件不好理解,那我們先建立一個物件,然後再呼叫,是不是就明白了呢,其實道理也就是這樣的,不過是換了一種形式
OutputEnglish english = new OutputEnglish();
board.showMess(english);
english.output(); // 這個,因為建立的物件裡有這個方法,所以直接呼叫也可以// 這個,紅括號裡面的就是他的引數,前面可以宣告一個物件再來引用,但對於匿名類是不能宣告的,所以就直接作為引數,在這裡面進行建立、寫類體。注意一下匿名類是如何建立的:new 父類名(){ 類體 }
board.showMess ( new OutputAlphabet() {
public void output() { //重寫父類方法
for(char c = '1';c <= '5';c++){
System.out.printf("\n" + "%3c",c);
}
}
}) ; //注意分號不要忘了
}
}
2.和介面有關的匿名類
與介面有關就是用介面名和類體來建立一個匿名類咯。 new 介面名 () { 類體 };
介面和類體組成的匿名類要求類體必須要重寫介面中的所有方法。
//介面定義
interface Speak{
void sp();
}
class Hello{
public void turn(Speak hello){ // 介面引數
hello.sp();
}
}
public class niming {
public static void main(String[] args) {
Hello HD = new Hello();
HD.turn ( new Speak(){
public void sp(){
System.out.println("Hello,you are welcom!");
}
} ) ;
}
}
三、異常類
Java中本身也是包含有很多類的,具體的作用方法我一個菜鳥還是記不住的,就遇到了再記吧。那現在關於異常類中的方法,我還是查一下吧,簡單的...
異常類的祖先是Throwable,throwable的直接子類是 Exception 和 Error。
異常物件可以呼叫下列方法得到或輸出有關異常的資訊:
public String getMessage(); //只顯示原因,不顯示類名
public void printStackTrace(); //跟蹤異常發生時堆疊的內容
public String toString(); //顯示類名和原因
Java允許方法呼叫過程中丟擲異常物件,終止當前方法的繼續執行。
1.try-catch語句
Java使用try-catch語句來處理異常,將可能出現的異常操作放在try-catch語句try部分,一旦try部分丟擲異常物件,或呼叫某個可能丟擲異常物件的方法,並且該方法丟擲了異常物件,(反正就是try語句裡有異常)那麼try部分立刻結束執行,轉向執行相應的catch部分。 故程式可以將發生異常後的處理放在catch部分,try-catch語句可以由幾個catch組成,分別處理髮生的相應異常。
其try-catch語句格式為:
try{
包含可能發生異常的語句
}
catch(ExceptionSubClass1 e){ ...... }
catch(ExceptionSubClass2 e){ ...... }
各個catch引數中的異常類都是Exception的某個子類,表明try部分可能發生的異常,這些子類間不能有父子關係,否則保留一個含有父類引數的catch即可。
public class yichang {
public static void main(String[] args) {
int n =0 ,m = 0, t = 1000;
try{
m = Integer.parseInt("8888");
n = Integer.parseInt("ab12");
t = 999;
}
catch(NumberFormatException e){
System.out.println("發生異常:" + e.getMessage());
}
System.out.println("n=" + n + ",m=" + m + ",t=" + t);
try{
System.out.println("故意丟擲I/O異常!");
throw new java.io.IOException("我是故意的");
// System.out.println("這個輸出語句是沒有機會被執行的");
}
catch(java.io.IOException e){
System.out.println("發生異常:" + e.getMessage());
}
}
}
java.lang包中的 Integer 類呼叫其類方法public static int parseInt(String s)可以將 “數字”格式 的字串, 如“6789”, 轉化為 int型資料 ,但是當試圖將字串“ab89”轉換成數字時,例如:int number=Integer.parseInt(“ab89”);方法parseInt()在執行過程中就會丟擲 NumberFormatException 物件,即程式執行出現NumberFormatException異常(字串轉換成數字異常)。
2.自定義異常類
可以自己編寫Exception的子類作為自己的異常類。使用 throws 關鍵字宣告要產生的異常(即在要判斷方法的方法名後面加throws 編寫的異常類類名),使用 throw 關鍵字丟擲該異常的物件,使該方法結束執行。
程式必須在try-catch塊語句中呼叫可能發生異常的方法,其中catch的作用就是捕獲throw關鍵字丟擲的異常物件。
//自定義的異常類,其實和普通的類一樣
public class BankException extends Exception{
String message;
public BankException(int m,int n) {
message = "若入賬資金"+m+"是負數,或者支出"+n+"為正數,則錯誤";
}
public String warn(){
return message;
}
}
public class Bank {
private int money;//判斷方法中是否有異常
public void income(int in,int out) throws BankException{ //宣告可能產生異常的類
if(in<0||out>0||in+out<0){
throw new BankException(in, out); //若發生了異常對其進行丟擲
}
int netIncom = in +out;
System.out.printf("本次純收入為:%d元\n",netIncom);
money = money + netIncom;
}
public int getMoney(){
return money;
}
}
public class yichang {
public static void main(String[] args) {
Bank bank = new Bank();
try{
bank.income(200, -50);
bank.income(300, -80);
bank.income(500, -100);
System.out.printf("銀行存款:%d元\n",bank.getMoney());
bank.income(100, 50); // 在這裡出現了異常,則立即結束執行
bank.income(6000, -20); // 不會被執行
}
catch(BankException e){
System.out.println("發生問題為:");
System.out.println(e.warn());
}
System.out.printf("銀行存款:%d元\n",bank.getMoney());
}
}
3.finally語句
finally語句使用在try-catch語句後面的
try{.....}
catch(ExceptionSubClass e){.....}
finally{.....}
在執行了try-catch語句後,執行finally語句,也就是說,無論try部分是否發生異常,finally語句都會被執行。
But,若try-catch語句中執行了程式退出程式碼( 即執行System.exit(0); ),則不會執行後面的所有語句(包括finally語句)。