抽象类和接口(抽象类和接口的区别和相同点)
抽象类
就像这个代码:
在这个打印图形的例子当中,可以看到父类的 shape 方法并没有实际作用,主要的工作都由子类完成了,像这些没有实际工作的方法,我们就可以把它设计成一个抽象方法,包含抽象方法的类叫做抽象类:
在 draw 方法前面加上 abstract 关键字就变成了抽象方法,但是包含抽象方法的类,必须用 abstract 修饰。
使用抽象类的注意事项
1.抽象方法不能直接实例化
报错如图:
2.抽象方法是不能用 private 修饰的
报错如图:
3.抽象类中可以包含其他的非抽象方法,也可以包含字段,这里的非抽象方法和普通方法的挥着都是一样的,可以被重写,也可以被子类直接调用,但是一个普通类要继承抽象类,那么必须重写抽象类当中的所有抽象方法。
运行结果如下:
抽象类的作用
抽象类存在的最大意义就是为了被继承,抽象类本身并不能被实例化,要想使用,只能创建该抽象类的子类,然后让子类重写抽象类中的抽象方法。在使用的时候,会多一重编译器的校验。因为直接使用父类的时候就会报错误。
接口
接口是抽象类的更进一步,抽象类中还可以包含非抽象方法和字段。而接口中包含的方法都是抽象方法,字段只能包含静态常量。
语法使用
在上面的打印图像代码当中,父类 shape 并没有包含别的抽象方法,所以就可以设计成一个接口。代码示例:
运行结果如下:
这里应该注意的是:
- 使用接口的时候,要用 interface 定义。
- 接口中的方法一定是 public ,因此可以省略 public 。
- 接口中的方法一定是抽象方法,因此可以省略 abstract 。
- Cycle 使用 implements 继承接口,此时表达的含义不再是“扩展”,而是“实现”。
- 在调用的时候同样可以创建一个接口的引用,对应到一个子类的实例。
- 接口不能单独被实例化。
接口当中只能包含抽象方法,对于字段来说,接口中只能包含静态常量:
代码当中的 public static final 关键字都可以省略,省略后的 num 仍然表示 public 静态常量。在创建接口的时候,接口的命名一般以大写字母 I 开头。
实现多个接口
有些时候我们需要让一个类同时继承多个父类,但是 Java 实现不了多继承。不过可以通过同时实现多个接口来达到多继承类似的效果。通过类来表示一组动物(通过接口来调用就不用关心引用是谁了):
运行结果如下:
在这里就可以利用接口来完成需要的功能,通过同时实现多个接口来完成功能。
使用接口给对象数组排序
通过接口对一个学术类进行排序:
运行结果如下:
通过龄完成了排序。比较的时候,通过 Comparable 来比较,进而完成排序。
接口间的继承
接口也可以继承一个接口(也叫扩展),达到复用代码的效果。也是使用 extends 关键字:
Clonable 接口和深拷贝
在 Object 类当中有一个 clone 方法,调用这个方法可以创建一个对象的“拷贝”,但是如果想要合法调用 clone 方法,必须要先实现 Clonable 接口,否则就会抛出异常:
这里在使用 clone 方法的时候,通过抛出异常,重写异常达到接口的使用,运行结果如下:
内存分布图如下:
如果把 age 改为 99 因为 person1 是克隆 person 的,所以person1 的 age 也变成 99 了。
如果在修改之后,继续对 person1 进行修改,就会改变 age 的值了。
运行结果如下:
这里的都是浅拷贝,之后在序列化的时候会学到深拷贝。