抽象类
像没有实际工作的方法,我们可以把它设计成一个抽象方法,包含抽象方法的类我们称为抽象类
abstract class Shape {
abstract public void draw();
}
- 在draw方法前面加上关键字abstract关键字,表示这是一个抽象方法,同时抽象方法没有方法体
- 对于包含抽象方法的类, 必须加上 abstract 关键字表示这是一个抽象类.
注意事项
1.抽象类不能直接实例化
public class Test2 {
Shape shape = new Shape() ;//这样编译会报错,因为抽象类不能被实例化
}
2.抽象方法不能时private
3.抽象类中可以包含其他的非抽象方法, 也可以包含字段. 这个非抽象方法和普通方法的规则都是一样的, 可以被重写,也可以被子类直接调用
抽象类的作用
抽象类存在的最大意义就是为了被继承
抽象类本身不能被实例化,要想使用, 只能创建该抽象类的子类. 然后让子类重写抽象类中的抽象方法.
使用抽象类相当于多了一重编译器的校验.使用抽象类的场景就如上面的代码, 实际工作不应该由父类完成, 而应由子类完成. 那么此时如果不小心误用成父类了,
使用普通类编译器是不会报错的. 但是父类是抽象类就会在实例化的时候提示错误, 让我们尽早发现问题.
接口
接口是抽象类的更进一步,抽象类还可以包含非抽象方法,和字段而接口中包含的方法都是抽象方法,字段只能包含静态常量
interface IShape {
void draw();
}
class Cycle implements IShape {
@Override
public void draw() {
System.out.println("○");
}
}
public class Test {
public static void main(String[] args) {
IShape shape = new Rect();
shape.draw();
}
}
- 接口中的方法一定是抽象方法,因此可以省略abstract
- 接口中的方法一定是public ,因此可以省略public
- 在调用的时候可以创建一个接口的引用,对应到一个子类的实例
- 接口不能单独被实例化
接口中只能包含抽象方法. 对于字段来说, 接口中只能包含静态常量(final static).
interface IShape {
void draw();
public static final int num = 10;
}
其中public static final 的关键字都可以省略,省略后的num仍然表示public 的静态常量
实现多个接口
Java只继承单继承,一个类只能extend一个父类,但是可以同时实现多个接口
接口使用实例
创建一个学生类
public class Student implements Comparable{
private String name;
private int score;
public Student(String name, int score) {
this.name = name;
this.score = score;
}
@Override
public String toString() {
return "(" + name + " : " + score + ")";
}
@Override
public int compareTo(Object o) {
//向下转型
Student s =(Student)o;
if(this.score > ((Student) o).score){
return 1;
}
if (this.score < ((Student) o).score){
return -1;
}
else {
return 0;
}
}
}
实现按照成绩降序
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
Student[] students = {
new Student("张三",93),
new Student("李四",92),
new Student("王五",98),
new Student("赵六",88)
};
System.out.println(Arrays.toString(students));
Arrays.sort(students);
System.out.println(Arrays.toString(students));
}
}
我们不能直接Arrays.sort(students),因为两个整数是可以直接比较的, 大小关系明确. 而两个学生对象的大小关系怎么确定?
在 sort 方法中会自动调用 compareTo 方法. compareTo 的参数是 Object , 我们在这里其实传入的就是 Student 类型的对象.
Arrays.sort()方法一定会调用compareTo方法,compareTo方法可以在Compareble接口中实现,所以我们让Student类实现这个接口,并且覆写compareTo,通过动态绑定可以在运行时达到我们想要的逻辑
我们可以尝试自己实现一个 sort 方法来完成刚才的排序过程(使用冒泡排序)
public static void sort(Comparable[] arrays){
for(int bound = 0;bound < arrays.length; bound++){
for(int cur = arrays.length - 1;cur > bound ;cur --){
if (arrays[cur - 1].compareTo(arrays[cur]) == 1){
Comparable tmp = arrays[cur];
arrays[cur] = arrays[cur - 1];
arrays[cur - 1] = tmp;
}
}
}
}
抽象类和接口的差别
1.抽象类里可以包含普通方法和普通属性,接口只能包含抽象方法和静态常量属性。
2.一个类只能继承自一个抽象类,一个类可以同时实现多个接口。
3.抽象类里的权限可以是各种权限,接口里的权限一定是public
4.一个用extends关键字继承,一个使用implements关键字实现接口
啥时候使用抽象类,啥时候使用接口呢?
本文探讨了Java中的抽象类和接口,包括它们的特点、用途和区别。抽象类主要用于被继承,不能直接实例化,可以包含抽象方法和非抽象方法。接口则更纯粹,仅包含抽象方法和静态常量,一个类可以实现多个接口。两者在权限、继承和实现方式上有所不同,选择使用抽象类还是接口取决于具体的设计需求。





