接口使用实例

给对象数组排序

两个学生对象的大小关系怎么确定? 需要我们额外指定.

这里需要用到Comparable 接口

java 接口类没有实现 java接口和接口实现类_ide


在Comparable 接口内部有一个compareTo 的方法,我们需要实现它

java 接口类没有实现 java接口和接口实现类_java 接口类没有实现_02


在下图中,我们需要将o强制转换为Student

java 接口类没有实现 java接口和接口实现类_System_03


之后调用Arrays.sort(array)即可完成排序,如下

java 接口类没有实现 java接口和接口实现类_开发语言_04


代码:

package demo5;

import java.util.Arrays;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: Home-pc
 * Date: 2023-08-16
 * Time: 16:40
 */
class Student implements Comparable{
    public String name;
    public double score;
    public Student(String name,double score){
        this.name=name;
        this.score=score;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", score='" + score + '\'' +
                '}';
    }


    public int compareTo(Object o) {
        Student student=(Student)o;
        if(this.score>student.score){
            return 1;
        }else if(this.score<student.score){
            return -1;
        }
        return 0;
    }
}
public class Test {
    public static void main(String[] args) {
        Student[] array=new Student[3];
        array[0]=new Student("zhangsan",80);
        array[1]=new Student("qwer",7);
        array[2]=new Student("asdfg",806);
        System.out.println("前"+ Arrays.toString(array));
        Arrays.sort(array);
        System.out.println("后"+ Arrays.toString(array));
    }
}

为了进一步加深对接口的理解, 我们可以尝试自己实现一个 sort 方法来完成刚才的排序过程(使用冒泡排序)

java 接口类没有实现 java接口和接口实现类_java 接口类没有实现_05


结果也是正确的

java 接口类没有实现 java接口和接口实现类_开发语言_06


扩展上面的内容,我们想分别按照年龄和分数排序

需要用到Comparator接口

java 接口类没有实现 java接口和接口实现类_开发语言_07


建立两个不同的类来实现这两种方法,都要实现Comparator接口

java 接口类没有实现 java接口和接口实现类_开发语言_08


结果如下

java 接口类没有实现 java接口和接口实现类_java_09


上述代码如下:

package demo5;

import java.util.Arrays;
import java.util.Comparator;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: Home-pc
 * Date: 2023-08-16
 * Time: 16:40
 */
class Student{
    public String name;
    public double score;
    public int age;
    public Student(String name,double score,int age){
        this.name=name;
        this.score=score;
        this.age=age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", score='" + score + '\'' +
                '}';
    }
}
class AgeComparator implements Comparator<Student>{

    @Override
    public int compare(Student o1, Student o2) {
        return o1.age-o2.age;
    }
}
class ScoreComparator implements Comparator<Student>{

    @Override
    public int compare(Student o1, Student o2) {
        return (int)(o1.score-o2.score);
    }
}
public class Test {

    public static void main(String[] args) {
        Student[] array=new Student[3];
        array[0]=new Student("zhangsan",80,89);
        array[1]=new Student("qwer",7,123);
        AgeComparator ageComparator=new AgeComparator();
        System.out.println(ageComparator.compare(array[0], array[1]));
        System.out.println("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
        ScoreComparator scoreComparator=new ScoreComparator();
        System.out.println(scoreComparator.compare(array[0], array[1]));
    }
}

抽象类和接口的区别

核心区别: 抽象类中可以包含普通方法和普通字段, 这样的普通方法和字段可以被子类直接使用(不必重写), 而接口中

不能包含普通方法, 子类必须重写所有的抽象方法.

抽象类存在的意义是为了让编译器更好的校验, 像 Animal 这样的类我们并不会直接使用, 而是使用它的子类.

万一不小心创建了 Animal 的实例, 编译器会及时提醒我们.

java 接口类没有实现 java接口和接口实现类_java_10


Clonable 接口和深浅拷贝

Object 类中存在一个 clone 方法, 调用这个方法可以创建一个对象的 “拷贝”. 但是要想合法调用 clone 方法, 必须要

先实现 Clonable 接口

如下所示,我们需要Student实现这个接口,需要对clone方法重写

java 接口类没有实现 java接口和接口实现类_开发语言_11


但是我们运行后发现还是报错

我们发现这里,点击添加Add

java 接口类没有实现 java接口和接口实现类_开发语言_12


运行发现继续报错,观察到红线这里,需要的类型为Student,我们提供的类型为Object,需要强制类型转换

java 接口类没有实现 java接口和接口实现类_ide_13


运行,拷贝成功

java 接口类没有实现 java接口和接口实现类_java 接口类没有实现_14


上述为浅拷贝


java 接口类没有实现 java接口和接口实现类_开发语言_15


java 接口类没有实现 java接口和接口实现类_java_16


结果并不理想,它把两个对象里的grade都改了,这种情况下没有构成深拷贝,拷贝的是grade的地址,它只是对Student对象中的内容进行了一份拷贝,但是并没有对,对象中的对象中的内容进行拷贝。

如何进行深拷贝?

我们改动以下部分

java 接口类没有实现 java接口和接口实现类_java_17


java 接口类没有实现 java接口和接口实现类_开发语言_18


java 接口类没有实现 java接口和接口实现类_java_19


java 接口类没有实现 java接口和接口实现类_ide_20


java 接口类没有实现 java接口和接口实现类_开发语言_21


java 接口类没有实现 java接口和接口实现类_ide_22


java 接口类没有实现 java接口和接口实现类_开发语言_23


Object类
Object是Java默认提供的一个类。Java里面除了Object类,所有的类都是存在继承关系的。默认会继承Object父
类。即所有类的对象都可以使用Object的引用进行接收。

使用Object接收所有类的对象

java 接口类没有实现 java接口和接口实现类_java 接口类没有实现_24


Object类是参数的最高统一类型。但是Object类也存在有定义好的一些方法
我们主要来熟悉这几个方法:toString()方法,equals()方法,hashcode()方法


Object类中的toString()方法实现,可以直接用编译器生成重写

java 接口类没有实现 java接口和接口实现类_System_25


对象比较equals方法

在Java中,java 接口类没有实现 java接口和接口实现类_java 接口类没有实现_26进行比较时:

a.如果java 接口类没有实现 java接口和接口实现类_java 接口类没有实现_26左右两侧是基本类型变量,比较的是变量中值是否相同

b.如果java 接口类没有实现 java接口和接口实现类_java 接口类没有实现_26左右两侧是引用类型变量,比较的是引用变量地址是否相同

c.如果要比较对象中内容,必须重写Object中的equals方法,因为equals方法默认也是按照地址比较的

java 接口类没有实现 java接口和接口实现类_System_29


结论:比较对象中内容是否相同的时候,一定要重写equals方法


hashcode方法

算出一个具体的对象位置

我们认为两个名字相同,年龄相同的对象,将存储在同一个位置,如果不重写hashcode()方法,我们可以来看示例

代码:

java 接口类没有实现 java接口和接口实现类_java 接口类没有实现_30


像重写equals方法一样,我们也可以重写hashcode()方法。

java 接口类没有实现 java接口和接口实现类_开发语言_31


java 接口类没有实现 java接口和接口实现类_System_32