day13
抽象類
1. 半成品,是沒有完成的類
2. 抽象方法的作用:
作為通用方法在父類中定義
要求子類必須實作
3. final
1. 常量, 值不可變
2. 方法, 不能重寫
3. 類, 不能繼承
4. static
1. 靜态屬于類的
2. 調用時,使用類名調用,也允許使用執行個體調用
3. 靜态的初始化塊
static{
類加載時執行,隻執行一次
}
5. 通路控制符
1. public
2. protected
3. default
4. private
6. 對象建立的過程 10步
1.
7. 接口
1. 作用: 結構設計工具,解耦合,隔離實作
2. interface
3. implements
4. 可以多實作,接口與接口之間可以多繼承
異常處理
封裝錯誤資訊的對象
錯誤資訊 有3點
1. 類型
2. 提示資訊
3. 行号
異常的繼承結構
Throwable
| - Error 系統級錯誤, 無法處理,隻能盡量讓程式安全的退出.
| - Exception 異常, 可修複的錯誤
| - 其他 Exception
| - RuntimeException
|
| - NullPointerException
| - ArrayIndexOutOfBoundsException
| - ArithmeticException 數學異常
| - NumberFormatException
| - ClassNotFoundException
| - ClassCastException
| - ...
異常的捕獲
try{
捕獲
}catch(A異常類型){
處理
}catch(B異常類型){
處理
}catch(Exception e){
父類型處理
} finally{
不管處不出錯,都必須執行
}
throws
在方法上添加異常的抛出管道
void f() throws A,B,C{
}
出現異常, 異常必須處理,處理的方式有兩種
1. catch
2. throws
注: 在方法上, 存在預設的異常管道, 凡是RuntimeException下的異常都可以在不加管道的情況下,抛出
練習1, 異常
package day301;
import java.util.Scanner;
public class Test1 {
public static void main(String[] args) {
while(true){
try {
f();
break;
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("輸入2個,不是一個");
}catch(ArithmeticException e){
System.out.println("不嗯呢該除零");
}catch (Exception e) {
System.out.println("出錯,請重試");
e.printStackTrace();
}finally {
System.out.println("-----------------");
}
}
}
private static void f() {
/*
* 輸入2個整數,用 ,号隔開
*/
System.out.println("請輸入2個整數,用 , 号隔開");
String s = new Scanner(System.in).nextLine();
//拆分,傳回一個數組
String[] a = s.split(",");
int m1 = Integer.parseInt(a[0]);
int m2 = Integer.parseInt(a[1]);
int r=m1/m2;
System.out.println(r);
}
}
測試 throws
package day301;
import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
public class Test2 {
public static void main(String[] args) {
try {
f();
} catch (ParseException e) {
System.out.println("日期格式錯誤");
} catch (IOException e) {
System.out.println("不能建立檔案");
}
}
private static void f() throws ParseException, IOException {
/*
* 輸入日期(yyyy-MM-dd) "2919-4-1"
*
* SimpleDateFormat 日期格式工具,把字元串解析成Date
*
* Date 執行個體中,封裝的是時間的毫秒值
* 取出毫秒值:3656456544
* 建立一個檔案 d:\3656456544.txt 檔案
*
*/
System.out.println("輸入日期(yyyy-MM-dd): ");
String s = new Scanner(System.in).nextLine();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
//強制處理異常
//必須事先考慮異常如何考慮,給出處理方案
Date d = sdf.parse(s);
String path="d:\\"+d.getTime()+".txt";
File file = new File(path);
file.createNewFile();
System.out.println("檔案已經建立"+path);
}
}
RuntimeException和其他 Exception差別
RuntimeException: 稱為"非檢查異常"
編譯期不會檢查這種異常,不便攜處理代碼也可以
其他Exception 稱為 "檢查異常"
編譯期會檢查這種異常,有沒有處理代碼,沒有代碼,編譯不會通過
兩種處理異常的方式: catch , throws
RuntimeException 就算不寫預設也會添加管道.
catch 和 throws 如何選擇?
如果是在底層代碼出現的錯誤,一般要向上層抛出,在調用路徑中,選擇一個合适的位置捕獲處理.
如果經驗不足,不知道如何選擇 catch 還是 throws, 就要用 throws,不能随便 catch.
throw
手動抛出異常,執行異常的抛出動作
當程式出現邏輯錯誤 ,而且不自動建立異常,可以手動建立異常對象,并手動抛出
throw e,優點相當于 return e ;的感覺
#### 測試 throw
package day301;
import java.util.Scanner;
public class test3 {
public static void main(String[] args) {
f();
}
private static void f() {
/*
* 5345/0 出現異常 ArithmeticException
*
* 32.5632 /0 -->Infinity 無窮大值 ,特殊值
* 不出錯, 沒有提示異常
* Infinity 沒有意義,我們需要處理這種資料異常
*/
System.out.println("輸入兩個浮點數:");
double a = new Scanner(System.in).nextDouble();
double b = new Scanner(System.in).nextDouble();
try {
double c=divide(a,b);
System.out.println(c);
} catch (ArithmeticException e) {
System.out.println("不能除零,是我們的錯");
e.printStackTrace();
}
}
private static double divide(double a, double b) {
if(b==0){
ArithmeticException e =
new ArithmeticException(" / by zero ");
throw e;
}
return a/b ;
}
}
異常包裝 捕獲的異常,包裝成另一種類型在抛出
為什麼要包裝後在抛出?
異常包裝使用用場景:
1. 不能抛出的類型,包裝成能抛出的類型
2. 異常的簡化
為什麼不能抛出? 不是加個管道就可以抛出了嗎?
如: 方法重寫時,異常管道,不能比父類方法的管道多.
異常包裝的測試:
package day301;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Test4 {
public static void main(String[] args) {
Student s = new Student("張三", "asda-06-12");
System.out.println(s);
}
}
class Student{
String name;
String birthday; //"1945-12-10"
public Student(String name, String birthday) {
super();
this.name = name;
this.birthday = birthday;
}
@Override
public String toString() {
// 張三 ,7854642131321(毫秒值)
// SimpleDateFormat 解析成Date 執行個體
// 從Date 中再取出毫秒值
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
Date d = sdf.parse(birthday);
return name+","+d.getTime();
} catch (ParseException e) {
/*
* Parseexception 是抛不出去的, 因為他不是RuntimeException類型的
* 而且 也不能 throws 加管道,因為 toString()是重寫父類object的,
* 父類中的toString() 沒有聲明管道,隻有預設的RuntimeException管道.
* 是以需要把他 包裝成 可以抛出的類型.
*/
throw new RuntimeException(e);
}
}
}
如果出現異常,他的異常資訊:
Exception in thread "main" java.lang.RuntimeException: java.text.ParseException: Unparseable date: "asda-06-12"
at day301.Student.toString(Test4.java:42)
at java.lang.String.valueOf(String.java:2982)
at java.io.PrintStream.println(PrintStream.java:821)
at day301.Test4.main(Test4.java:10)
Caused by: java.text.ParseException: Unparseable date: "asda-06-12"
at java.text.DateFormat.parse(DateFormat.java:366)
at day301.Student.toString(Test4.java:32)
... 3 more
自定義異常類型
業務中的錯誤情況,用現有的異常類型是無法表示的,
如 轉賬失敗, 就沒有合适的異常來表示
我們的自定義異常 隻不過是起一個符合這個異常描述的名字,我們也隻是需要一個合适的名字.
轉賬異常:
ZhuanZhangShiBaiException
使用者名錯誤
usernameNotFoundException
密碼錯誤
WrongPassworldException
自定義異常:
1. 起一個合适的類名
2. 選擇一個合适的異常父類, 可以繼承runtimeException或者 Exception都可以,但注意的是 RuntimeException 是預設的管道,不用throws也可以抛出.
3. 添加合适的構造方法
自定義異常 測試
自定義 2個異常,
一個使用者名異常,
一個密碼異常.
如下:建立類:
package day301;
public class usernameNotFoundException extends Exception{
/*
* 在寫自定義異常的構造時 ,參考父類的寫法,
* Shift+Alt+ s ----->
*
*/
public usernameNotFoundException() {
super();
}
public usernameNotFoundException(String message, Throwable cause, boolean enableSuppression,
boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
public usernameNotFoundException(String message, Throwable cause) {
super(message, cause);
}
public usernameNotFoundException(String message) {
super(message);
}
public usernameNotFoundException(Throwable cause) {
super(cause);
}
}
package day301;
public class WrongPassworldException extends Exception{
public WrongPassworldException() {
super();
}
public WrongPassworldException(String message, Throwable cause, boolean enableSuppression,
boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
public WrongPassworldException(String message, Throwable cause) {
super(message, cause);
}
public WrongPassworldException(String message) {
super(message);
}
public WrongPassworldException(Throwable cause) {
super(cause);
}
}
package day301;
import java.util.Scanner;
public class Test5 {
public static void main(String[] args) {
System.out.println("使用者名: ");
String n = new Scanner(System.in).nextLine();
System.out.println("密碼: ");
String p = new Scanner(System.in).nextLine();
try {
login(n,p);
System.out.println("登陸成功");
} catch (usernameNotFoundException e) {
System.out.println("使用者名不存在");
}catch (WrongPassworldException e) {
System.out.println("密碼錯誤");
}
}
private static void login(String n, String p) throws usernameNotFoundException, WrongPassworldException {
// "abc" ,"123"
if (!n.equals("abc")) {
throw new usernameNotFoundException();
}
if (!p.equals("123")) {
throw new WrongPassworldException();
}
}
}
IO
Input/ Output
輸入 / 輸出
輸入: 外部資料,讀取到記憶體,有程式進行處理
輸出: 記憶體中的資料,向外部輸出
java.io 包
1. File
2. InputStream /OutputStream
3. FileInputStream/ fileOutputStream
4. ObjectInputStream /ObjectOutputStream
5. Reader /Writer
6. InputStreamReader /OutputSteramWriter
7. BufferedReader
8. PrintWriter
File 類
用來封裝磁盤路徑字元串
File 執行個體={ path: "d:\a.txt"}
可以封裝:
1. 檔案路徑
2. 檔案夾路徑
3. 不存在的路徑
内部提供了一些方法:
檔案或檔案夾屬性方法:
1. getName() 擷取檔案名
2. getParent() 擷取父檔案夾 (路徑)
3. getAbsolutePath() 完整路徑 ,絕對路徑
4. exists() 是否存在,判斷這個路徑是否存在, 傳回值 boolean
5. isFile() 是否是檔案
6. isDirectory() 是否是檔案夾
7. length() 擷取檔案的位元組量, 對檔案夾無效
屬性方法測試: