一.什么是接口?
抽象类是对行为的抽象,而接口类是一种行为规范/定义
定义方式
public interface 类名{
}
1.对行为的抽象
抽象类中的方法的活动是子类都有一个方法,那就在父类中抽象去定义这个方法
抽象类相当于是一种模板设计
2.行为的规范/定义
接口中只能使用抽象方法,只能定义行为/方法
void run();
3.接口类不能创建对象,只能使用多态
二.如何实现接口
public class 类名 implements 接口名{
}
三.接口和类的区别
接口可以多继承,一个类可以实现多个接口------------设计接口的目的之一:实现java的多继承
但是在接口中,并不去实现某一个方法,只是对方法进行定义
举例:
Animal接口:
public interface Animal {
//在接口中,并不去实现某一个方法,只是对方法进行定义
public abstract void run();
}
A接口:
public interface A {
public void flay();
}
Cat类:
public class Cat implements Animal,A{
//实现接口,意味着实现接口里的方法
@Override
public void flay() {
}
@Override
public void run() {
}
}
四.接口的特点
1.接口是一种行为规范/定义
2.接口中只能使用抽象方法,所以不用写abstract关键字,默认也是public访问修饰符修饰的,所以也不用写public
3.接口类不能创建对象,只能使用多态
4.一个类可以实现多个接口(设计接口的目的之一:实现java的多继承)
五.接口和抽象类的使用
1.在servlet中,任何一个servlet都要继承HttpServlet
只有继承HttpServlet,才能使用doGet()方法、doPost()方法
2.HttpServlet类中
在HttpServlet中,它继承了GenericServlet,而且HttpServlet是一个抽象类
3.GenericServlet类中
在GenericServlet中,它实现了Servlet接口,并且GenericServlet也是一个抽象类
4.Servlet接口中
Servlet接口中,有五个方法:
五个方法的作用:
1.init()
初始化
2.getServletConfig()
获取servlet的配置
3.service()
服务
4.getServletInfo()
获取servlet信息
5.destroy()
销毁
流程:创建–服务–销毁
我们可以定义为生命周期
5.接口中定义的方法必须去实现,如果不想实现,把自己定义成abstract
举例:
Animal接口:
public interface Animal {
//在接口中,并不去实现某一个方法,只是对方法进行定义
public abstract void run();
}
A接口:
public interface A {
public void flay();
}
Cat类:
不想实现run()方法,传给下一个
public abstract class Cat implements Animal,A{
@Override
public void flay(){
}
public abstract void run();
}
6.流程
GenericServlet实现Servlet接口
Servlet接口中定义了servlet的生命周期(从创建到销毁)-----这也是接口本身功能的体现:对行为的定义
HttpServlet继承GenericServlet(抽象类)
GenericServlet中实现了除了service()方法之外的其他的关于生命周期的方法
自定义的servlet类继承HttpServlet(抽象类)
HttpServlet类中实现了service()方法
上面这一系列的方法有人定义、有人实现,所以我们自定义的servlet类只需要继承HttpServlet就可以使用上面一系列的方法
结论:
抽象类的设计的目的之一:更好的实现接口当中定义的方法
六.关于排序的例题
1.基本数据类型的排序
Test类:
public class Test {
public static void main(String[] args) {
int[] arr=new int[]{5,7,4,2,0,3,1,6};
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
}
}
输出:
如何对引用数据类型的数据排序?
例:
Person类:
public class Person implements Comparable<Person> {
private Integer age;
private Integer height;
public Person(int age, int height) {
this.age = age;
this.height = height;
}
@Override
public String toString() {
return "Person{" +
"age=" + age +
", height=" + height +
'}';
}
}
Test类:
public class Test {
public static void main(String[] args) {
Person p1=new Person(22,180);
Person p2=new Person(20,190);
Person p3=new Person(18,170);
Person p4=new Person(23,181);
Person[] persons=new Person[]{p1,p2,p3,p4};
Arrays.sort(persons);
System.out.println(Arrays.toString(persons));
}
}
输出:
报错,对象是无法排序的,无法调用到Comparable
如何解决:
在Person类中实现Comparable接口
Person类:
public class Person implements Comparable<Person> {//再使用一下泛型
private Integer age;
private Integer height;
public Person(int age, int height) {
this.age = age;
this.height = height;
}
@Override
public String toString() {
return "Person{" +
"age=" + age +
", height=" + height +
'}';
}
//实现排序的核心方法(排序是数值类型的排序)
@Override
public int compareTo(Person o) {
//指定age从小到大进行排序:age-o.age;
//指定age从大到小进行排序:o.age-age;
return age-o.age;
}
}
Test类:
public class Test {
public static void main(String[] args) {
Person p1=new Person(22,180);
Person p2=new Person(20,190);
Person p3=new Person(18,170);
Person p4=new Person(23,181);
Person[] persons=new Person[]{p1,p2,p3,p4};
Arrays.sort(persons);
System.out.println(Arrays.toString(persons));
}
}
输出:
2.重写sort()方法
数组类型只能是Comparable,因为不管写什么类,都要实现Comparable接口,就意味着这些类的父类是Comparable,那我们就可以利用向上转型转成Comparable(多态),假如写Person类,那别的类(比如Student类)调用sort()方法就不能传参了,所以最好是用父类的类型
(1)用冒泡排序重写sort()方法:
比较大小那里不能用加减,需要调用compareTo()方法,因为有可能比较的是引用数据类型的数据
public class Array2 {
public static void sort(Comparable[] arr){
for(int j=0;j<arr.length;j++){
for(int i=0;i< arr.length-j-1;i++){
//进行判断用compareTo
if(arr[i].compareTo(arr[i+1])>0){//如果前一个值比后一个值大,交换
Comparable temp=arr[i];
arr[i]=arr[i+1];
arr[i+1]=temp;
}
}
}
}
}
(2)用快速排序重写sort()方法:
public class Array3 {
public static void sort(Comparable[] arr,int left,int right){
if (left < right) {
// 获取分区后的枢纽位置
int pivotIndex = partition(arr, left, right);
// 分别对枢纽左右两边的子数组进行递归排序
sort(arr, left, pivotIndex - 1);
sort(arr, pivotIndex + 1, right);
}
}
private static int partition(Comparable[] arr, int left, int right) {
// 选择数组的最后一个元素作为枢纽值
Comparable pivot = arr[right];
int i = (left - 1);
// 遍历数组,将小于枢纽值的元素放到左边,大于枢纽值的元素放到右边
for (int j = left; j < right; j++) {
if (arr[j].compareTo(pivot)<0) {
i++;
// 交换 arr[i] 和 arr[j]
Comparable temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
// 将枢纽元素放到正确的位置
Comparable temp = arr[i + 1];
arr[i + 1] = arr[right];
arr[right] = temp;
// 返回枢纽位置
return i + 1;
}
}
(3)Test类:
public class Test {
public static void main(String[] args) {
Person p1=new Person(22,180);
Person p2=new Person(20,190);
Person p3=new Person(18,170);
Person p4=new Person(23,181);
Person[] persons=new Person[]{p1,p2,p3,p4};
Array2.sort(persons);
System.out.println(Arrays.toString(persons));
Array3.sort(persons,0,persons.length-1);
System.out.println(Arrays.toString(persons));
}
}
输出: