天天看点

CGB-SE-day13day13

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()  获取文件的字节量, 对文件夹无效
           

属性方法测试: