1 继承
1.1 abstract
1.2 接口
2 多态
3 内部类
4 对象操作流
结束
1 继承
Java只能单继承,不可以多继承,但支持多层继承
1.1 abstract
abstract 修饰类和方法,使用原因是因为在继承中会有父类可以抽取出子类中类似的方法,但具体的实现每个子类都不一样,如果父类中写一个完整的方法结构没有实际意义,不会使用到,我们就在父类中只声明这个方法,不去具体实现,也就是使用 abstract(在普通方法上增加abstract,去掉方法体,也就是{},然后加分号即可)这样父类使用了 abstract,子类中就必须重写这个方法了,必须进行具体实现。
有抽象方法的类只能定义成抽象类,抽象类里可以没有抽象方法,也可以有非抽象方法(这个方法就可以实现子类中完全相同的行为)
抽象类不能创建对象,原因是有未实现的方法,若可以创建对象,对象无法调用。但有构造器,因为需要为类中的成员变量进行初始化
abstract不可以与final、private共存
1.2 接口
特点:
接口定义的是一种规范,是一种设计哲学,将规范与实现分离
使用interface关键字 默认使用public修饰符
[修饰符] interface 接口名 extends 父接口1, 父接口2... { 零到多个常量定义... 零到多个抽象方法定义 ... 零到多个内部类、接口、枚举定义 ... 零到多个默认方法或类方法定义 ... }
接口中不能包含构造器和初始化代码块。
接口中的成员变量只能是静态常量(public static final),必须指定默认值。
接口里所有成员都是public访问权限,可以省略访问控制符。
接口中的方法只能是抽象方法、类方法和默认方法,默认方法系统会自动添加 public abstract修饰,普通方法不能有方法实现,但类方法、默认方法必须有方法实现。
接口的实现
一个类可以实现多个接口(不必担心实现的接口中存在重名的抽象方法的情况,因为接口中并没有具体实现,调用的时候只会调用具体实现的类中的方法体),是为单继承灵活性不足做的补充。一个类实现了一个或者多个接口之后,这个类必须完全实现这些接口里所定义的全部抽象方法(另外需要注意一点,类是不需要重写默认的方法的,但当实现的多个接口中有重名的默认方法时,则必须重写默认方法)
接口不能实例化
2 多态
子父类继承、方法重写、父类引用指向子类对象
Animal a = new Dog();
父类引用 指向 子类对象
涉及到动态绑定,父类无法访问子类特有的成员
成员变量:编译时左边,运行时左边(不涉及多态)
成员方法:编译时左边(父类类型),运行时右边(子类)(有重写,涉及多态)
静态方法:都是左边,不涉及多态,因为静态方法相当于类名调用,就是父类类名调用。
3 内部类
匿名内部类:适合创建那种只需要一次使用的类。创建匿名内部类时需要立即创建该类的一个实例(因为该类匿名,除此之外再也没有其他方式创建对象了)
new 实现接口() | 父类构造器 (实参列表) { // 匿名内部类的类体部分 }
匿名内部类必须继承一个父类或实现一个接口,但最多只能继承一个父类或实现一个接口。
使用场景:实现某个接口的类所创建的对象只需使用一次,则可以定义一个匿名内部类
4 对象操作流
可以用以读写任意类型的对象
ObjectOutputStream
写出方法:writeObject
构造方法:ObjectOutputStream(OutputStream out)
ObjectInputStream
输入方法:readObject
构造方法:ObjectInputStream(InputStream in)
注意:使用对象输出流写出对象,只能使用对象输入流来读取对象;只能将支持 java.io.Serializable 接口的对象写入流中。每个 serializable 对象的类都被编码,编码内容包括类名和类签名、对象的字段值和数组值,以及从初始对象中引用的其他所有对象的闭包。
public interface Serializable介绍
类通过实现 java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化。可序列化类的所有子类型本身都是可序列化的。序列化接口没有方法或字段,仅用于标识可序列化的语义。
当一个类实现.Serializable接口,并利用对象输出流写出对象到文件时,其写出的对象是附带一些属性的,其中serialVersionUID这一字段用来指定其对应的类,当我们没有自己指定时,会有Java虚拟机生成一个,但在对类进行修改后这个数字会相应改变,于是当我们对已经写出到文件的对象其对应的进行修改时,会导致读入流无法找到对应的类,从而导致出错(java.io.InvalidClassException),这就需要我们提前对实现Serializable的类设置一个private static final long serialVersionUID的属性,唯一标识一个类,这样对类的修改就可以了。
一个tip:在使用对象输入流读数据的时候,我们无法预先得知文件中有多少个对象,所以在读到文件末尾时会出现 EOFException 的异常,为避免此异常,可以在使用对象输出流写出数据的时候进行一些操作,也就是将写出的数据保存在一个集合数据结构中,统一写入,然后读取的时候只需要读取一次即可,然后将其转换为对应的集合类型进行操作即可。