【JavaSE】:接口(二)

接口

  • 一.对学生进行排序
  • 二.Clonable接口
  • 三.抽象类和接口的区别
  • 四.Object类

一.对学生进行排序

【JavaSE】:接口(二)_第1张图片

在这里插入图片描述

很明显我们直接对学生进行排序是会报错的,因为编译器也不知道你需要按照名字排还是分数排,我们点击报错位置进入sort内部。

在这里插入图片描述

在sort内部我们可以看到它把数组转换成立一个Comparable类型。而这个Comparable是一个接口型,而这个接口里有一个compareto方法,我们需要实现这个接口。

import java.util.Arrays;

class Student implements Comparable<Student>{
    String name;
    int score;

    public Student(String name, int score) {
        this.name = name;
        this.score = score;
    }

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

    @Override
    public int compareTo(Student o) {
        if(this.score<o.score) return 1;
        else if(this.score>o.score) return -1;
        else return 0;
    }
}

public class sort {
    public static void main(String[] args) {
        Student[] st=new Student[3];
        st[0]=new Student("张三",28);
        st[1]=new Student("李四",100);
        st[2]=new Student("王麻子",63);

        Arrays.sort(st);//排序
        System.out.println(Arrays.toString(st));//打印出来
    }
}

在这里插入图片描述

但是这样写有一个很明显缺点,就是写死了。它这个类就只能按年龄比较,为了更加灵活,java又提供了另一个接口comparator。

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

class Student{
    String name;
    int score;

    public Student(String name, int score) {
        this.name = name;
        this.score = score;
    }

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

//灵活方法
class Scompare implements Comparator<Student>{

    @Override
    public int compare(Student o1, Student o2) {
        if(o1.score<o2.score) return 1;
        else if(o1.score>o2.score) return -1;
        else return 0;
    }
}

public class sort {
    public static void main(String[] args) {
        Student[] st=new Student[3];
        st[0]=new Student("张三",28);
        st[1]=new Student("李四",100);
        st[2]=new Student("王麻子",63);

        //使用
        Scompare s=new Scompare();

        Arrays.sort(st,s);//排序
        System.out.println(Arrays.toString(st));//打印出来
    }
}

在这里插入图片描述

二.Clonable接口

Java 中内置了一些很有用的接口, Clonable 就是其中之一

【JavaSE】:接口(二)_第2张图片

Object 类中存在一个 clone 方法, 调用这个方法可以创建一个对象的 “拷贝”。但是要想合法调用 clone 方法, 必须要先实现Clonable 接口, 否则就会抛出 CloneNotSupportedException 异常。object是所有类的父类(即使你没有写任何继承)。

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

class Student implements Cloneable{
    String name;
    int score;

    public Student(String name, int score) {
        this.name = name;
        this.score = score;
    }

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

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
public class sort {
    //因为克隆会抛出一个异常,所以main函数也需要声明异常
    public static void main(String[] args) throws CloneNotSupportedException{
        Student A=new Student("张三",60);
        //因为克隆方法是object里的,object是所有类的父类
        //这里相当于向下转,所以需要强转转型
        Student B=(Student) A.clone();

        System.out.println(B);
    }
}

在这里插入图片描述

上面我们仅仅是调用的object的克隆方法会问题,更改一下代码

【JavaSE】:接口(二)_第3张图片

【JavaSE】:接口(二)_第4张图片

这里出现了问题,我们只对A的money进行了修改,就跟B的money也发生了改变,不符合我们的预期。

【JavaSE】:接口(二)_第5张图片

因为我们仅仅将A里Money类的地址进行了拷贝,所以两者指向的Money对象自然是同一个,接下来实现一下让他们指向不同Money。

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


class Money implements Cloneable{
    public double money=12.5;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

class Student implements Cloneable{
    public String name;
    public int score;
    public Money m=new Money();
    public Student(String name, int score) {
        this.name = name;
        this.score = score;
    }

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

    @Override
    protected Object clone() throws CloneNotSupportedException {
        //克隆了student对象
        Student stu=(Student) super.clone();
        //克隆了student里的money对象
        stu.m=(Money) this.m.clone();
        return stu;

    }
}
public class sort {
    //因为克隆会抛出一个异常,所以main函数也需要声明异常
    public static void main(String[] args) throws CloneNotSupportedException{
        Student A=new Student("张三",60);
        //因为克隆方法是object里的,object是所有类的父类
        //这里相当于向下转,所以需要强转转型
        Student B=(Student) A.clone();

        System.out.println(A.m.money);
        System.out.println(B.m.money);
        System.out.println("#########");
        A.m.money=52.2;
        System.out.println(A.m.money);
        System.out.println(B.m.money);

    }
}

【JavaSE】:接口(二)_第6张图片

【JavaSE】:接口(二)_第7张图片

三.抽象类和接口的区别

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

【JavaSE】:接口(二)_第8张图片

四.Object类

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

例如

在这里插入图片描述

所以在开发之中,Object类是参数的最高统一类型。但是Object类也存在有定义好的一些方法。如下:

【JavaSE】:接口(二)_第9张图片

例如为什么在写了toString后printlen就会自动调用toString呢

【JavaSE】:接口(二)_第10张图片

printlen实际上是用object类接收的,然后再调用了一个valueof。

【JavaSE】:接口(二)_第11张图片

而valueof也是用object类接收,它就会调用自己写的toString。

你可能感兴趣的:(JavaSE,java,开发语言)