28.接口的基本语法
接口只是定义了数据交换的标准(定义了接口就是定义了调用对象的标准)
接口当中所有方法都是public,接口里面的方法都是抽象方法,接口中默认不是default 而是public
interface USB{
public void read();
void write();
//接口当中默认权限不是default,而是public
//接口里面的方法都是抽象方法
}
implements(实现是一种特殊的继承) 一个类实现一个接口
class USBPhone implements USB{
//复写接口中的抽象方法
//implements记得加s
public void read(){
}
public void write(){
//必须加上public权限,不然会报错
}
}
一个类可以实现(implement)多个接口(虽然java不接受多继承)
一个接口可以继承(extends)多个接口
class USBPhone implements USB,WIFI{
//就算实现多个接口implements也是要加s
//复写USB,WIFI中的方法
}
向上转型时有两种选择
USBPhone phone = new USBPhone();
USB usb = phone;
usb.read();
WIFI wifi = phone;
wifi.open();
一个接口可以继承多个接口
public interface Minter extends WIFI,USB {
}
29.接口的应用
工厂方法模式-把生成对象的代码(使用类来生成对象的方法)封装在工厂类中
30.Java当中的异常(一)
工厂方法模式-把生成对象的代码(使用类来生成对象的方法)封装在工厂类中
30.Java当中的异常(一)
异常:中断了正常指令流的事件
异常是一种对象,在程序产生异常时,虚拟机会生成一个异常对象(异常是由虚拟机为我们创建的)。既然异常是一个对象,那么就需要生成异常的类,这些类都是由JDK提供的,就像String这个类一样,是由JDK提供的
异常是在程序运行的时候产生的,与编译无关
//编译能通过,运行时会打印出1和异常信息
public class Test {
public static void main(String args[]){
System.out.println(1);
int i = 1/0;//属于uncheck excption
System.out.println(2);
}
}
异常类之间的继承关系
异常分为两大类:Error 和 Exception。程序员对Error无能为力,只能处理Exception
Error:一旦产生了错误,虚拟机就会关闭。而程序是运行在虚拟机上的,虚拟机关闭,程序自然会结束。
Exception:被分为两大类:运行时异常(
RuntimeException)
,编译时异常
(uncheck exception 和 check exception)
uncheck exception包括RuntimeException 以及
RuntimeException的子类。Exception 这个类以及 除了
RuntimeException和
RuntimeException的子类的
其他类 都属于check exception
(RuntimeException 属于 uncheck Exception ,Exception 属于 check Exception)
public class Test {
public static void main(String args[]){
//产生check exception,编译器强制要求对异常进行处理,不然编译不会通过
Thread.sleep(1000);
}
}
try ... catch...
将可能出现异常的代码放在try中,如果出现异常,会跳到catch中执行,catch块执行完后,会执行try...catch...的下一条语句。如果不出异常,catch中的代码不会执行。
public class Test {
public static void main(String args[]){
try{
//try块 放有可能出现异常的代码
//如果一旦出现异常,就会跳到catch块中执行
int i = 1/0;
}catch(Exception e){
//Exception e :虚拟机产生的异常对象
e.printStackTrace();
//打印异常的追踪信息
}
}
}
finally:无论出不出异常,finally块中都会执行,在finally中经常做一些
清理工作,比如关闭文件,数据库等.
例:打开、关闭文件
try{
//打开文件的代码
...
}catch{
}finally{
//关闭文件的代码
//这样无论出不出异常,都会关闭文件
}
try...catch...finally
把可能出现异常的代码放在try里面,把对异常进行处理的代码放在catch里,把清理资源的代码放在finally里
31.Java当中的异常(二)
throw 抛出异常.
,throws
声明异常
public class User {
private int age;
void setAge(int age){
if(age <0){
//生成一个RuntimeException的异常对象,传入参数为异常信息
RuntimeException e = new RuntimeException("年龄不能为负数");
throw e;
//抛出uncheck 异常,如果没有用try..catch处理,虚拟机就会终止代码的运行
}
this.age = age;
}
}
但是如果抛出一个check exception,编译器就会强制要求对这个异常进行处理(捕捉(try...catch)或者声明以便抛出),否则编译不能通过
1.捕捉用try...catch...finally
2.声明用throws
把throws紧跟在函数的后面 + 可能出现的异常类
public class User {
private int age;
//void setAge(int age) throws Exception这句话的意思是
//setAge这个函数有可能产生Exception这种类型的异常对象
//产生了这个异常之后,这个异常并不由setAge这个函数来处理,而是在调用这个函数的地方来处理
void setAge(int age) throws Exception{
if(age <0){
Exception e = new Exception("年龄不能为负数");
throw e;
}
this.age = age;
}
}
声明throws之后不会报错,但是在调用的地方会报错,因为在调用的时候没有对这种check
exception进行处理
在调用这个函数的时候对异常进行处理try...catch...
public class Test {
public static void main(String args[]){
User user = new User();
try{
user.setAge(5);
}catch(Exception e){
e.printStackTrace();
}
}
}
throw的作用:如果Java虚拟机判断不了某些情况(比如年龄输入为负数),那么可以在出现这种情况的时候生成一个异常对象,然后抛出这个异常
throws的作用:声明一个函数有可能出现异常,当这个函数不对这个异常进行处理,而是在调用这个函数的时候来对这个异常进行处理。
32.Java中的IO(一)
IO流的流向是以java程序为参照的
文件 文件
键盘 输入 Java程序 输出 屏幕
网络 网络
IO流:相当于一个管道,数据不是一次性输入输出,而是通过管道一点一点流进来
IO分类:
1.输入流
输出流
2.字节流:读取数据的时候,以字节为基础,每次输入/输出都是一个或几个字节
字符流:..... 以字符为基础 .......
3.节点流:是真正处理数据的IO流
处理流:在节点流的基础上对数据进行操作,提供额外的功能
IO中的核心类
//属于字节流的核心类
InputStream,OutputStream (抽象类--不能生成对象) ---所有字节流的父类
FileInputStream ----从硬盘的文件中读取数据
FileOutputStream ----将数据写入硬盘的文件中
InputStream : int read(byte [] b,int off,int len)
//byte [] b 从硬盘读进来的数据放在 比特类型的数组b 里
//int off 偏移量(读进来的数据从数组的第几位开始放)(一般是0)
//int len 读取一次最多读多少数据(一般是数组的长度)
//返回值int :这一次调用read()方法总共读取了多少字节的数据,当文件读取完,会返回-1
OutputStream: void write(byte []b,int off,int len)
//从数组b的第off位开始往硬盘中写入数据,一共写入len位
例:从文件中读出数据 (E:\aaa)中from.txt
总共四字节
1.导入类
2.用try...catch...(因为会产生check exception)
3.声明输入流引用
4.生成一个输入流对象,传入参数 文件的路径
5.生成一个字节数组
6.调用输入流对象的read方法,读取数据
//第一步骤:导入类
import java.io.*;
public class Test {
public static void main(String args[]){
//声明输入流引用
FileInputStream fis = null;
try{
//生成一个输入流对象,传入参数 文件的路径,这个路径下的文件一定要存在,不然会报错
fis = new FileInputStream("E:/aaa/from.txt");
//注意路径写的是左斜杠
//生成一个字节数组
byte [] buffer = new byte[10];
//调用输入流对象的read方法,读取数据
fis.read(buffer,0,buffer.length);
for(int i = 0 ;i<buffer.length;i++){
System.out.println(buffer[i]);
}
}catch(Exception e){
e.printStackTrace();
}
}
}
结果如下 (把字符转化成ASCII以字节的方式读取进来,abcd 四字节),buffer 10字节,剩下全是0
0对应空字符
将字节数组还原成字符
String s = new String(buffer);
System.out.println(s);
调用一个String对象的trim()方法,将会去除掉这个字符串的首尾空格和空字符
s = s.trim();
//第一步骤:导入类
import java.io.*;
public class Test {
public static void main(String args[]){
//声明输入流引用
FileInputStream fis = null;
//声明输出流的引用
FileOutputStream fos = null;
try{
//生成一个输入流对象,传入参数 文件的路径,这个路径下的文件一定要存在,不然会报错
fis = new FileInputStream("E:/aaa/from.txt");
//生成代表输出流的对象 ,如果这个文件不存在,会在此目录下自动创建一个
fos = new FileOutputStream("E:/aaa/tto.txt");
//生成一个字节数组
byte [] buffer = new byte[10];
//调用输入流对象的read方法,读取数据
int temp = fis.read(buffer,0,buffer.length);
//第三个参数应该是read()的返回值(返回值是总共读取了多少字节的数据)
fos.write(buffer,0,temp);
// String s = new String(buffer);
//s = s.trim();
// System.out.println(s);
}catch(Exception e){
e.printStackTrace();
}
}
}
如果write方法第三个参数改为 buffer.length,写入的数据后面会有一串null
fos.write(buffer,0,buffer.length);
33.Java中的IO(二) 字符流 字节流
大文件的读写方法(用循环实现)
例:用字节流从文件中读出数据 (E:\aaa)中from.txt 到 tto.txt
//read():当文件读取完,会返回-1
int temp = fis.read(buffer,0,buffer.length);
//第一步骤:导入类
import java.io.*;
public class Test {
public static void main(String args[]){
//声明输入流引用
FileInputStream fis = null;
//声明输出流的引用
FileOutputStream fos = null;
try{
//生成一个输入流对象,传入参数 文件的路径
fis = new FileInputStream("E:/aaa/from.txt");
//生成代表输出流的对象 ,如果这个文件不存在,会在此目录下自动创建一个
fos = new FileOutputStream("E:/aaa/tto.txt");
//生成一个字节数组
byte [] buffer = new byte[1024];
while(true){
//调用输入流对象的read方法,读取数据
int temp = fis.read(buffer,0,buffer.length);
if(temp == -1){
break;
}
//第三个参数应该是read()的返回值
fos.write(buffer,0,buffer.length);
}
}catch(Exception e){
e.printStackTrace();
}
}
}
在finally中关闭文件流,注意:这两个close()会抛出check exception ,需要再写一层try...catch
finally{
try{
fis.close();
fos.close();
}catch(Exception e1){
e1.printStackTrace();
}
}
字符流类似
字符流:读写文件时,以字符为基础
字符输入流:Reader <--FileReader
int read(char [] c , int off , int len)
字符输出流:Writer <--FileWriter
void write(char [] c , int off , int len)
例:用字符流将数据从
from.txt ---> to.txt
import java.io.*;
public class Test {
public static void main(String args[]){
FileReader fr = null;
FileWriter fw = null;
try{
fr = new FileReader("e:/aaa/from.txt");
fw = new FileWriter("e:/aaa/to.txt");
char [] buffer = new char[1024];
while(true){
int temp = fr.read(buffer,0,buffer.length);
if(temp == -1){
break;
}
fw.write(buffer,0,temp);
}
}catch(Exception e ){
e.printStackTrace();
}finally{
try {
fr.close();
fw.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
字符流效果好像更好
字节流
字符流
34.
Java中的IO(三)
节点流 处理流
字符输入处理流 BufferedReader readLine()方法
public String readLine() throws IOException
//可以一次性读取一行信息,当读取到最后一行时,返回null
生成BufferedReader对象的方法
BufferedReader in = new BufferedReader(new FileReader("fool.in"));
凡是要使用处理流的时候,首先必须要有一个节点流
filereader = new FileReader("e:/aaa/Users.txt");//节点流
bufferedReader = new BufferedReader(filereader);//处理流
BufferedReader不仅仅可以用来装饰FileReader(从文件中读取),还可以装饰从键盘读取
例:读取 Users.txt 中的每一行
import java.io.*;
public class Test {
public static void main(String args[]){
FileReader filereader = null;
BufferedReader bufferedReader = null;
try{
filereader = new FileReader("e:/aaa/Users.txt");
bufferedReader = new BufferedReader(filereader);
String line = null;
while(true){
line = bufferedReader.readLine();
if(line == null){
break;
}
System.out.println(line);
}
}catch(Exception e){
e.printStackTrace();
}finally{
try{
filereader.close();
bufferedReader.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
}
readLine()并不是真正从文件中读取,实际上是使用FileReader来读取数据。读取完之后,readLine对读取出来的数据进行进一步处理。
但是运行的结果 中文会显示乱码
装饰者模式(Decorator Pattern)
装饰者和被装饰者 将被装饰者的对象作为参数传入装饰者
例:有m个公司,有n个工种。按照正常继承,应该就有m x n个子类
1.定义一个Worker(工人)接口
public interface Worker {
public void doSomeWork();
}
2.
Plumber (
水管工),
Carpenter(
木匠) implements 工人(Worker)
public class Plumber implements Worker {
public void doSomeWork(){
System.out.println("修水管");
}
}
public class Carpenter implements Worker{
@Override
public void doSomeWork() {
System.out.println("修门窗");
}
}
3.新建A公司的员工AWorker implements Worker
public class AWorker implements Worker {
private Worker worker;
public AWorker(Worker worker){
this.worker = worker;
}
@Override
public void doSomeWork() {
// TODO Auto-generated method stub
System.out.println("你好");//相当于装饰,是A公司特有的操作
worker.doSomeWork();
//Plumber 或者 Carpenter 的操作,取决于传入的参数
}
}
AWorker 有一个 Worker类型的引用。
当需要水管工的时候,构造参数中传入 Plumber ;当需要木匠的时候,传入Carpenter。
public class Test {
public static void main(String args[]){
//生成一个A公司水管工对象
//先生成一个水管工对象,再把水管工作为参数传入AWorker
Plumber plumber = new Plumber();
AWorker aWorker = new AWorker(plumber);
aWorker.doSomeWork();
}
}
被装饰者(比如节点流):真正实现了功能
装饰者(比如处理流): 在被装饰者功能的基础上添加新的功能
装饰者和被装饰者 将被装饰者的对象作为参数传入装饰者