您的位置 首页 java

Java高级——文件与I/O流

简介

本文分为四个部分,首先是介绍 File 类,概括了一下概念、构造方法及常用方法等,其次是描述了面对对象的三大特征,再次是对 抽象类 进行了简单的概述,最后从特性、使用等等几个方面对接口进行了一定的描述。


一、File类

1、File类概念

(1) 代表硬盘上的一个文件或者文件夹。
  (2) Windows中路径表示方式 c:suns.txt
  (3) Java中路径表示方式:① c:suns.txt ;② c:/sun.txt

2、File类的构造方法

(1) File(String pathname)

 import  java . io .File;
import java.io.IOException;

public class FileTest {
    public static void main(String[] args) {
        createNewFile();
    }
    public static void createNewFile() {
        File file = new File("D:/File/javaFile.txt");
        try {
            // 创建新的文件,前提是必须文件夹已经存在,即D:/File已经存在,文件夹名字不区分大小写:
            file.createNewFile();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

  

(2) File(String parent, String child)

 import java.io.File;
import java.io.IOException;

public class FileTest {
    public static void main(String[] args) {
        createNewFile();
    }

    public static void createNewFile() {
        String url = "D:/File";
        String fileName = " HelloWorld.java";
        //有参构造方法
        File file = new File(url, fileName);
        try {
            // 创建新的文件,前提是必须文件夹已经存在,即D:/File已经存在,文件夹名字不区分大小写:
            file.createNewFile();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

  

(3) File(File parent, String child)
注意 : File类没有无参构造方法

3、File类的常用方法

(1) createNewFile(): boolean ;创建新的文件,前提是必须文件夹已经存在,文件夹名字不区分大小写。

 import java.io.File;
import java.io.IOException;

public class FileTest {
    public static void main(String[] args) {
        createNewFile();
    }
    public static void createNewFile() {
        File file = new File("D:/File/javaFile.txt");
        try {
            // 创建新的文件,前提是必须文件夹已经存在,即D:/File已经存在,文件夹名字不区分大小写:
            file.createNewFile();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

  

(2) mkdir() / mkdirs():boolean;创建一个完整的路径,即包括所有的上层目录 ,前提是父文件夹已经存在;mkdirs()可以建立多级文件夹, mkdir()只会建立一级的文件夹。

 import java.io.File;
public class FileTest {
    public static void main(String[] args) {
        createNewFile();
    }
    public static void createNewFile() {
        File file1 = new File("D:/File/java");
        File file2 = new File("D:/File/java/html");
        //只能创建一级文件夹,如果不小心写了多级,运行后不会报错,但是文件夹不会创建文件夹
        file1.mkdir();
        //可以创建多级文件夹
        file2.mkdirs();
    }
}

  

(3) delete() :boolean:删除已存在的文件或文件夹,最终调用native本地方法 立即进行删除
  (4) deleteOnExit():boolean:调用后,不会立即删除,会等到虚拟机正常运行结束后,才去删除
  (5) delete() :boolean:删除已存在的文件或文件夹,最终调用native本地方法 立即进行删除
  (6) delete() :boolean:删除已存在的文件或文件夹,最终调用native本地方法 立即进行删除
  (7) exists() :boolean:判断文件是否存在,只写文件名就行,不需要写全路径
  (8) isFile() :boolean:判断是否是一个文件
  (9) isDirectory() :boolean:判断是否是一个文件夹

(3) 对象创建之后就可以使用“对象名.对象成员”的格式来访问对象的成员(包括属性和方法)。
  (4) 创建对象时,每new一次就会创建一个新对象:
  例如:在一个Person类中进行一下两次new,都调用  shout()方法,会创建两个不同的对象。
  new Person().shout();
  new Person().shout();
  (5) 匿名对象:
    ① 不定义对象的名字,只通过new创建一个对象;这样的对象叫做匿名对象。如:new Person();
    ② 如果对一个对象只需要进行一次方法调用,那么就可以使用匿名对象。
    ③ 普通调用:Person p1 = new Person();p1.shout();
    ④ 普通调用:匿名调用:(new Person()).shout();
  (6) 判断创建的对象是否是同一个对象:
    ① 通过instanceOf();。
    ② 对象.getClass().getName();获取对象的实例类名。
  
补充 :详解请看下面多态中的:(7)判断多态后对象的实际类型。
  (7) Java中创建( 实例化 )对象的五种方式:
    ① 用new语句创建对象,这是最常见的创建对象的方法。
    ② 通过工厂方法返回对象,如:String str = String.valueOf(23);
    ③ 运用反射手段,调用java.lang.Class或者java.lang.reflect.Constructor类的 newInstance()实例方法。如:Object obj =         Class.forName(“java.lang.Object”).newInstance();
    ④ 调用对象的clone()方法。
    ⑤ 通过I/O流(包括反序列化),如运用反序列化手段,调用java.io.ObjectInputStream对象的 readObject()方法。
  (8) 在类中定义全局对象:即将对象定义成类中的属性。

 public class Zi  extends  Fu {
    // 定义全局对象
    public static Zi zi = new Zi();
    public static void eat() {
        System.out.println("子类中方法被调用");
    }
    public void test() {
    //Zi zi1 = new Zi(); 类方法中可以创建自己的对象,但是没什么意义
        super.eat();
    }
    public static void main(String[] args) {
        zi.eat();
        zi.test();
    }
}

  

二、面向对象的三大特征

1、封装性

(1) 封装优点:
    ① 隐藏对象的属性和实现细节。
    ② 使用者只能通过事先制定好的方法访问数据,限制对属性的不合理操作。
    ③ 增强代码的可维护性。
  (2) 实现封装:
    ① 方法就是一种封装。
    ② 使用private关键字:
      A:属性私有化,
      B:通过public方法对属性操作(getXxx()方法获取值setXxx()方法设置值),
      C: setXxx()方法有参数无返回值,参数类型与返回值类型相同,getXxx()方法无参数有返回值,返回值类型与参数类型相同。
      
注意: 对于基本类型当中的boolean值,Getter方法一定要写成isXxx()的形式,而setXxx()不变。
  (3) this关键字:
    ① this表示对当前对象的引用。
    ② this的作用:
      A:在构造方法和set方法中区分成员变量和方法参数。
      B:在本类中可以直接通过this.属性和this.方法调用成员变量和方法。
      C: 可以在构造方法中调用本类的其他构造方法:
        a:调用其他构造方法语句必须在第一行。
        b:不能出现构造方法递归调用,会发生死循环,编译出错。
        c:在实例方法中不能通过this()调用构造方法。
      
注意 :this()与super()两种构造调用不能同时使用。
    ③ this不能在静态方法中使用,但是可以在实例方法中通过this.静态方法进行调用。
原因 :this代表当前对象,在实例化之后,而静态方法在初始化阶段。
    ④ 在实例方法中调用其他实例方法,相当于this.方法();
    ⑤ 通过谁调用的方法谁就是this。

2、继承性

(1)继承介绍
    ① 关键字:extends(若省略extends,则为Object的子类)。
    ② 通过继承可以实现代码的复用。
    ③ Java不支持多继承,可以多重继承。
    ④ 用final修饰的类不能被继承。
  (2) 父类
    ① 定义:被继承的类称为父类。
    ② 父类包括所有直接或间接被继承的类。
  (3)
子类
    ① 定义:作为另一个类的扩充或修改而定义的类,继承而来的类称为子类。
    ② 子类不能继承访问权限为private的成员变量和方法。通过继承,子类对象可以直接去使用父类中非私有的方法和属性。
    ③ 在子类中可以通过super.方法或属性直接调用父类的非私有方法或属性。
    ④ 在子类的构造方法中可以通过super()的方式调用父类的构造方法:
      A:只能在子类的构造方法中调用父类的构造方法。
      B:调用父类的构造方法时只能使用super(…)。
      C: 不要在调用父类构造方法前加入其它的代码即super()必须放在第一行。
      D:如果子类没有调用,默认调用无参的super()。
      E:在同一构造方法中不能同时使用super和this去调用其它构造方法。
      F: 调用方式:
        a:调用父类成员方法:super.方法名(参数);
        b:调用父类构造方法:super(参数);
    ⑤ 子类的构造方法中至少一个通过super()去调用父类的构造方法。
    ⑥ 如果父类没有默认的无参构造方法,子类构造方法中必须显式调用父类的其他构造方法。
  (4) 有父子类的情况下初始化和实例化的顺序:
    ① 父类静态变量静态代码块。
    ② 子类静态变量和静态代码块。
    ③ 父类的实例变量和实例代码块。
    ④ 父类的构造方法。
    ⑤ 子类的实例变量和实例代码块。
    ⑥ 子类的构造方法。
  (5) 变量的访问特点:
    ① 变量不重名情况:
       直接通过子类对象访问成员变量:父类对象或者多态后的父类类型的子类对象调用变量
是用 的父类中定义的变量,子类对象调用变量则是使用的子类中的变量。
    ② 变量重名情况:
       间接通过成员方法访问成员变量:即:成员方法中使用到了该属性。则该方法属于父类就是用的是父类的变量,该方法属于子类则使用的是子类中的变量。
  (6) 区分子类方法中重名的变量方法:
    ① 局部变量:直接写成员变量名。
    ② 本类的成员变量:this.成员变量名。
    ③ 父类的成员变量:super.成员变量名。
  (7)继承中成员方法的访问:
    ① 创建的对象是谁的,就优先使用谁中定义的方法。

  Zi zi = new Zi();//创建子类对象
 Zi.methodFu();//父类中的方法执行了
 Zi.methodZi();//子类中定义的方法执行了
 Zi.method();//子类中重写父类的方法执行了

  

(8)super关键字的三种用法:
    ① 在子类的成员方法中,访问父类的成员变量。
    ② 在子类的成员方法中,访问父类的成员方法。
    ③ 在子类的构造方法中,访问父类的构造方法。
  (9)super与this关键字案例:

 //定义父类
public class Fu {
    public Fu() {
        System.out.println("父类无参的构造方法被调用了");
    }

    public Fu(int a, int b) {
        System.out.println("父类含参的构造方法被调用了,a+b="+(a+b));
    }

    public void run() {
        System.out.println("父类的实例方法");
    }
}

  
 //定义子类通过this与super关键字调用父类中的方法
public class Zi extends Fu {
    public Zi() {
        this(1, 2);
        System.out.println("子类的构造方法被调用了");
    }
    public Zi(int a, int b) {
        // super(a, b);
        System.out.println(a + b);
    }
    public void run() {
        super.run();
        System.out.println("子类的实例方法");
    }

    public static void main(String[] args) {
        Zi zi = new Zi();
        Zi zi1 = new Zi(1, 2);
        zi.run();
    }
}

  
 //输出的结果
父类无参的构造方法被调用了
3
子类的构造方法被调用了
父类含参的构造方法被调用了,a+b=3
3
父类的实例方法
子类的实例方法

  

(10)Java继承的三个特点:
    ① 一个类的直接父类只有唯一一个,没有继承其他类时候,默认继承Object类。
    ② Java语言可以多重继承。
    ③ 一个之类的父类是唯一的,但是一个父类可以有很多个之类。

3、多态性

(1) 定义:允许将子类类型的对象定义成父类类型的一种技术,多态是通过子类重写父类的方法来实现的。但是如果该方法是静态的,多态就不起作用。(或者是final的也不行)。
  (2) 多态存在的前提条件:
    ① 继承
    ② 方法重写
    ③ 父类引用指向子类对象
  (3) 多态的运行机制:靠的是父类或接口定义的引用变量可以指向子类或具体实现类的实例对象,而程序调用的方法在运行期才动态绑定,就是引用变量所指向的具体实例对象的方法,也就是内存里正在运行的那个对象的方法,而不是引用变量的类型中定义的方法。
  (4) 多态作用:把不同的子类对象都当做父类来看,屏蔽不同子类对象之间的差异,写出通用的代码,做出通用的编程,以适应需求的不断变化。
  (5)使用多态方式调用方法时:
    ①(首先检查父类中是否存在该方法)若不存在,则编译错误原因:多态后会屏蔽子类独有的属性和方法。
    ② 若存在,则去调用子类的同名方法。
    ③ 多态后不能调用父类的私有方法。
    ④ 静态方法不能多态,不能被重写。
    ⑤ 使用多态不能调用子类独有的方法。只能调用子类中重写父类的方法。如果子类中没有重写父类的方法,默认调用父类中的方法。
    ⑥ 不能调用子类独有的属性,只能调用父类中的属性,如果父类和子类都有的属性,则调用的是父类里面定义那个变量,输出的是父类那个变量的值。
    ⑦ 多态后的对象不能调用父类中用private修饰的私有的构造方法。
    
注意 :使用多态调用子类与父类同名的静态方法,调用的是父类中的静态方法,不是子类中的,因为静态方法与用final修饰的方法都不能被重写。
  (6)多态后属性不会被重写:
    ① Super super=new Son();父类引用指向子类对象,
    ②
子类 中也有同名属性,
    ③ super.变量名:调用的父类的变量。
  (7)判断多态后对象的实际类型:
    ① 通过 对象A.instanceof(对象B);
      A:判断对象是否是某个类的实例。

 //判断ani是否是 Dog 类型的对象
if(ani instanceof Dog){
    return ture;
    }

  

B:缺点:不够准确,若是某个类的子类,也会返回true 。

 Animai ani = new Husky();//Husky继承了Dog,Dog又继承了Aniaml
     if(ani instanceof Dog){
    return ture;
    }

  

② 对象.getClass().getName()取得该类真正的类名。

 if(ani.getClass().getName().equals(Dog.class.getName())) {
    return ture;
          } else {
    return false;
        }

  

(8) 多态的两种体现:
    ① 父类引用指向子类对象。
    ② 实现类对象定义为接口类型。
  (9) 方法绑定:
    ① 静态方法绑定:将方法的调用绑定到类上,通过类名.方法进行调用。
    ② 动态方法绑定:将方法的调用绑定到对象上,通过对象.方法进行调用。

三、抽象类

1、抽象类的概念:抽象类用来描述一些具有通用概念的类,用 abstract 修饰的类。

2、抽象类的特性:

(1)抽象类不能实例化,但是可以创建一个继承该抽象类的匿名内部类对象,该匿名内部类也要将抽象类中的所有抽象方法实现。new 抽象类名() {
public void 方法名() {……}
   (2)抽象类中不一定有抽象方法,但是有抽象方法的类一定是抽象类。
   (3)一个类如果继承一个抽象类,则需要:实现抽象类中所有的抽象方法或者该类仍为一个抽象类,就不用实现所有抽象方法。

(4)抽象类只能做父类,供其他类继承,不能用final修饰。
   (5)抽象类中可以有构造方法和静态方法,但是静态方法和构造方法不能是抽象的。

(6)抽象类可以定义变量。
   (7)可以通过多态将匿名内部类对象定义为抽象类类型。
   (8)创建子类对象的时候,会隐式调用抽象父类的构造方法。

3、抽象方法:抽象方法是指使用abstract修饰,并且只定义了方法头,而没有方法体和具体实现的方法,抽象方法只能存在于抽象类中,可以带参数。

4、抽象类与普通类的区别:

(1)抽象类中可能有抽象方法,普通的类没有抽象方法
   (2)抽象类不能实例化,普通类的可以进行实例化。
   (3)抽象类不能用final修饰,普通类可以。

四、接口

1、接口的概念:接口是一种特殊形式的抽象类,表示某种或某些相关的行为或方法或能力。接口中所有的方法全部都是抽象的接口中所有的方法全部都是抽象的(目前可以这样理解,后面会补充,接口中还可以定定义其他方法)。

2、接口的定义规则:接口的定义语法:

  [public] interface 接口名 [extends 父接口名] {
     ……    // 常量定义和方法定义
 }

  

注意 :接口interface前面的权限修饰符只能是public与默认,不写的话是默认的。

3、接口的特性:抽象类用来描述一些具有通用概念的类,用abstract修饰的类。

4、抽象类的特性:

(1)接口中不能有构造方法。
   (2)接口中在jdk1.8之后是可以定义静态方法的。
   (3)接口中的方法默认是public abstract修饰的,可以不写abstract。

(4)接口中的变量默认是public static final修饰,即接口中只有静态常量没有变量。
   (5)多态的第二种实现:将实现类对象定义为接口类型。
   (6)多态后只能调用重写后的方法,不能调用实现类自己的方法,子类的属性也不能调用。

5、接口的使用:

(1)类可以通过implements对接口进行实现。
    ① 实现类实现接口必须全部实现接口中的抽象方法。
    ② 如果没有全部实现抽象方法,则实现类必须为抽象类。
    ③ 一个类可以实现多个接口。
    ④ 接口可以通过extends继承其他接口,一个接口可以继承多个接口。
   (2)接口的多态以及普通方法的使用:
    ①接口不可以实例化;但是接口对象可以指向它的实现类对象。
    ② 通过实现接口而定义的实现类对象只能使用对应接口中的方法。
    ③通过创建匿名内部类对象.方法名调用。
   (3)接口中常量的调用:
    ① 直接通过接口的实现类
对像 .属性调用。
    ② 通过创建匿名内部类对象.属性调用。
   (4)接口中的其它方法:
    ① 静态方法:静态方法不能被重写,所以在接口实现类中不需要写出。
    
注意: 接口中的静态方法只能通过接口名.方法名调用,不能通过实现类对象.方法名来调用。
    ② 默认方法:
      A:接口中用default修饰的方法(注意,不是什么都不写,和权限修饰符里面的默认修饰符不一样)。
      B:接口中的默认方法可以有方法体,默认方法不需要在接口实现类中写出。
      C: 在接口的实现类的其他方法中可以通过默认方法名,直接调用接口中的默认方法;也可通过实现类对象.方法名来调用。
      D:接口中的默认方法是可以进行重写与重载的,但是重写的默认方法不能带default。

6、接口和抽象类的区别:

(1)定义不同:抽象类是用abstract修饰的类,接口的关键字是interface。
   (2)成员变量不同;接口中的成员默认使用public static final修饰,接口中只有静态常量。
   (3)构造方法:抽象类中可以定义构造方法与静态方法,接口中没有构造方法,但jdk1.8后可以定义静态方法。
   (4)使用:一个类只能继承一个抽象类,但是可以实现多个接口。
   (5)继承:抽象类可以实现接口,而接口不能继承抽象类。
   (6)抽象类和抽象类之间只能单继承,而接口与接口之间可以进行多继承。
   (7)实质关系上:
    ① 抽象类:一个继承抽象类表示该类和抽象之间的关系为is a的关系,即子类是抽象类。
    ② 接口:一个类实现了某个或多个接口,实现类和接口关系为has a的关系,即实现类拥有接口的某些能力。
   (8)可定义方法类型上:

     

Java高级——文件与I/O流


注意 :B接口中有一个方法,B接口又继承了C接口,C接口中有两个与B接口中不一样的方法,如果A实现了B接口,则A需要实现B接口中与C接口中的所有方法。

7、通过接口创建匿名内部类对象:

(1)通过new接口可以创建一个默认的实现该接口的匿名内部类对象。
   (2)可以将匿名对象定义为接口类型。
   (3)多态后的匿名内部类对象不能直接调用匿名内部类中自己独有的方法和全部属性。
   (4)可以通过匿名内部类对象直接进行调用自己的方法和属性,且只能调用一次。

结尾

本文到这里就结束了,感谢看到最后的朋友,都看到最后了,点个赞再走啊,如有不对之处还请多多指正。

文章来源:智云一二三科技

文章标题:Java高级——文件与I/O流

文章地址:https://www.zhihuclub.com/181921.shtml

关于作者: 智云科技

热门文章

网站地图