java抽象类和接口(Comparator和Conparable的使用)
1.抽象类
抽象类是一种类,但是他和普通的类有一些区别,抽象类中可以定义抽象方法,当子类继承该类的时候,需要重写抽象方法,相当于加了一重检查机制
定义:
来看具体实现
总结汇总:
1.抽象类中可以有普通的变量和变量名,静态的方法和变量
我们看这段代码在编译器上面并没有报错
2. 抽象类中的抽象方法在被子类继承的时候,必须要被重写(子类不是抽象方法)
通过这三幅图可以很直观的看出来,当我们不重写父类中的抽象方法的时候,编译器会报错
3.抽象方法要写成();的格式,而且抽象方法不能有具体的实现
这里我们可以看到,在抽象方法的后面如果加上的是大括号,就会报错,体现出了抽象方法不能有具体实现
4.普通方法不能写成();的格式
当我们给普通方法写成这种形式的时候,编译器会报错
5.当子类为抽象类时,可以不重写抽象方法,但是当我们再来一个普通类继承 子类的时候,就必须把所有的抽象方法都重写
这里我们需要重写两个抽象方法,否则编译就不通过
6.可以用内部类在实例化的时候,进行重写抽象方法
在这里,我们利用抽象内部类,对抽象方法进行了重写,一样能过编译
但是当我们不使用内部类的时候,也就是抽象类中的抽象方法没有被重写的时候,就会报错
7.抽象方法是不能被private修饰的
因为我们的抽象方法是用来被重写的,但是当我们对他使用private进行修饰的时候,在类外就得不到访问权限,从而导致编译报错
注意:抽象方法没有加访问限定符,默认是加上public,和普通类不同,普通类是default
8.抽象方法不能被final和static修饰
可以看到这两个,都报红了,因为如果被fina修饰或者被static进行修饰之后,就不能重写抽象类中的方法了
2.接口
我们在生活中也有很多接口,比如,usb接口,type-c接口等等
在我们的java中也有接口,因为java本身是不支持多继承的,但是接口的出现,让我们有类似多继承的办法
总结汇总:
定义:
接口其实我们可以参照抽象类来理解,接口比抽象类更加抽象一些
看具体的使用方法
1.接口的创建
接口的创建方法和类相似,只需要用interfac就可以创建了
注意:这里的接口是友好型的,是同一个包中可以访问的,如果我们想要用public修饰
2.接口中的方法和抽象方法一样,不能有具体实现,需要将接口声明在A.java的文件中
可以看到当我们给接口加上大括号的时候,编译器就报错了
因为接口中的变量都是默认有修饰符的
可以看到,这里我们用public 和abstract修饰的时候,修饰符的颜色变暗了,因为我们的接口是默认给加上这两个限定符的
3.接口是引用类型,但是不能实例化
这里可以看到,当我们进行实例化的时候,编译报错了,但是接口是引用类型,可以和抽象类一样,进行匿名内部类对抽象方法进行重写
4.接口的使用
只需要在需要使用接口的类那里加上implement既可以了
在实现了接口的类中,进行抽象方法的重写即可
5. 重写接口中方法时,不能使用访问权限修饰符
因为我们的接口是默认的public权限,所以我们在重写的时候,只能使用比原修饰符更大的修饰符,所以不能用出了publilc之外的修饰限定符
6.接口中可以含有变量
可以看到这里和上面的一样,是暗色的,所以是默认修饰符
7. 接口中不能有静态代码块和构造方法
可以看到,我们使用代码块的时候,就会报错,因为我们的接口变量都是隐式修饰的,不能修改,并且不能加其他的限定符,所以接口中的静态代码块就没意义了
8.接口编译完成后,生成的字节码文件也是.class
9.如果类中没有实现接口中的所有方法,我们必须要把该类定义成抽象类
和前面的抽象类中的原因是一致的
10.在jdk8中接口可以包含default方法了
注意:这里的default不是访问限定符
可以看到是暗色的
注意:接口时可以继承的,这里就不测试了
接口和抽象类的区别
3.一些重要的接口的使用
目录
3.一些重要的接口的使用
3.1Comparable
3.2Comparator
3.1Comparable
这个接口是用来进行对象直接的比较的
比如我们创建一个类Student实例化student1和student2的对象,然后调用Comparable接口中的compareTo方法来进行比较
class Student{
public int age;
public int results;
public Student(int age,int results){
this.age = age;
this.age = results;
}
}
public class Main {
public static void main(String[] args) {
Student student1 = new Student(18,80);
Student student2 = new Student(14,90);
}
}
然后我们开始使用Comparable接口,只需要在原来的上实现这个接口,并且重写CompareTo方法就行了
//这里的<>是泛型的意思,里面放的就是Comparable和CompareTo参数的类型
class Student implements Comparable<Student>{
public int age;
public int results;
public Student(int age,int results){
this.age = age;
this.results = results;
}
@Override
public int compareTo(Student o) {
return this.age - o.age;
}
}
public class Main {
public static void main(String[] args) {
Student student1 = new Student(18,80);
Student student2 = new Student(14,90);
System.out.println(student1.compareTo(student2));
}
}
这段代码的执行结果就是
但是在这里我们发现,这个比较方法,对类的侵入性太强了,我们这时候如果想要比较成绩,就会发现无从下手,所以我们引出了另外一个接口compar
3.2Comparator
这个叫做比较器,是可以把比较的内容和原来的类进行分离操作的,所以对类的侵入性低,代码的耦合性就低
import java.util.Comparator;
class Student{
public int age;
public int results;
public Student(int age,int results){
this.age = age;
this.results = results;
}
}
class ageComparator implements Comparator<Student>{
@Override
public int compare(Student o1, Student o2) {
return o1.age - o2.age;
}
}
class resultsComparator implements Comparator<Student>{
@Override
public int compare(Student o1, Student o2) {
return o1.results - o2.results;
}
}
public class Main {
public static void main(String[] args) {
Student student1 = new Student(18,80);
Student student2 = new Student(14,90);
// System.out.println(student1.compareTo(student2));
//这里使用了匿名内部类,去调用两个比较器
System.out.println(new ageComparator().compare(student1,student2));
System.out.println(new resultsComparator().compare(student1,student2));
}
}
注意:使用Comparator接口的时候,需要导包