类和对象进阶 - 接口

1. 接口

1.1 接口定义与重点

1. 使用 interface关键字定义接口

public interface 接口名称{
    
}

2. 接口中的方法不能有具体的实现

不能有具体的实现 是因为接口中的方法默认都是抽象方法

3. 如果要有具体实现 必须用default / static修饰 

4. 在接口中定义的成员变量 默认都是用public static final修饰的常量

5. 接口中的抽象方法 默认都是用public abstract修饰的

7. 接口不能用来实例化对象

8. 类和接口之间的关系 可以使用implements来关联

9. 一个类 继承一个普通类/抽象类 还可以同时关联接口

10. 一个类实现接口后 必须重写接口中的抽象方法

11.  如果类没有实现接口中的所有的抽象方法,则类必须设置为抽象类

12. 接口和接口之间可以使用关键字extends。表示某个接口拓展了某个接口的功能。
interface A extends B,C,D {}   

13. 子类继承抽象类或者关联接口后,可以用抽象类/接口引用 引用子类对象 发生向上转型 

1.2 理解接口

完整代码:

https://github.com/znxcmakhsd/JavaSE-code/tree/main/11-23/demo2

1.3 抽象类和接口的区别

1. 抽象类中可以有普通的成员变量和方法 但是接口中的成员变量只能是public static final 接口中的成员方法只能是public abstract抽象方法

2. 一个类只能继承一个抽象类 但是一个类可以实现多个接口 所以接口解决了java中不能多继承的问题

2. 几个重要的接口

2.1 comparable接口

如何比较两个对象的大小 ?

用 > 比较运算符 ? 


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

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

}

public class Main {
    public static void main(String[] args) {
        Student student1 = new Student("abc",18);
        Student student2 = new Student("abd",19);
        if (student1 > student2) {
            System.out.println("student1 > student2");
        }
    }
}

不能用>比较对象 因为比较运算符两边的操作数只能是 基本类型整数或浮点数 
比如: 1 > 2  1.1 > 1.2

那么 用什么办法比较对象 ?

这个问题稍后回答 先来看如何比较两个字符串大小

package demo2;

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

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

}

public class Main {
    public static void main(String[] args) {
        Student student1 = new Student("abc",18);
        Student student2 = new Student("abd",19);

        String str1 = "abc";
        String str2 = "abd";
        if (str1.compareTo(str2) >= 0) {
            System.out.println("str1 >= str2");
        }else {
            System.out.println("str1 < str2");
        }

    }
}

如图 str1 < str2 成功比较出了字符串的大小 但是 它是怎么比较的 原理是什么?

首先java中的字符串是对象 str1是"abc"这个字符串对象的引用 所以str1这个对象的引用可以访问String类中的方法 

String类实现了Compareable这个接口 然后重写了Compareable接口中的compareTo方法 如下图

所以 比较字符串大小 实际上调用的是String类自己的compareTo方法进行比较的

我们也可以模仿这种方法 对我们自己的对象进行比较

package demo2;

class Student implements Comparable<Student>{
    public String name;
    public int age;
    public Student(String name,int age) {
        this.name = name;
        this.age = age;
    }

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

    @Override
    public int compareTo(Student o) {
        // 用名字进行比较
        //return this.name.compareTo(o.name);
        // 用年龄进行比较
        return this.age - this.age;
    }
}

public class Main {
    public static void main(String[] args) {
        Student student1 = new Student("abc",20);
        Student student2 = new Student("abd",19);
        if (student1.compareTo(student2) >= 0) {
            System.out.println("student1 >= student2");
        }else {
            System.out.println("student1 < student2");
        }
    }
}

用名字比较:

用年龄进行比较:

接下来 有个重要的问题是 为什么一定要实现compareable这个接口 ?

我们自己是可以写一个函数进行比较的 如下例

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

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

    /*@Override
    public int compareTo(Student o) {
        // 用名字进行比较
        //return this.name.compareTo(o.name);
        // 用年龄进行比较
        return this.age - this.age;
    }*/
    public int my_compareTo(Student o){
        // 用名字进行比较
        //return this.name.compareTo(o.name);
        // 用年龄进行比较
        return this.age - this.age;
    }
}

public class Main {
    public static void main(String[] args) {
        Student student1 = new Student("abc",20);
        Student student2 = new Student("abd",19);

        if (student1.my_compareTo(student2) >= 0) {
            System.out.println("student1 >= student2");
        }else {
            System.out.println("student1 < student2");
        }
    }
}

这个问题的回答通过下例说明

package demo2;

import java.util.Arrays;

class Student /*implements Comparable<Student>*/{
    public String name;
    public int age;
    public Student(String name,int age) {
        this.name = name;
        this.age = age;
    }

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

    /*@Override
    public int compareTo(Student o) {
        // 用名字进行比较
        //return this.name.compareTo(o.name);
        // 用年龄进行比较
        return this.age - o.age;
    }*/

    public int my_compareTo(Student o){
        // 用名字进行比较
        //return this.name.compareTo(o.name);
        // 用年龄进行比较
        return this.age - o.age;
    }

}

public class Main {
    public static void main(String[] args) {
        Student student1 = new Student("a",20);
        Student student2 = new Student("c",19);
        Student student3 = new Student("b",21);
        Student[] arr = {student1,student2,student3};
        Arrays.sort(arr);
        System.out.println(Arrays.toString(arr));
    }

    /*public static void main1(String[] args) {
        Student student1 = new Student("abc",20);
        Student student2 = new Student("abd",19);

        if (student1.my_compareTo(student2) >= 0) {
            System.out.println("student1 >= student2");
        }else {
            System.out.println("student1 < student2");
        }
    }*/
}

如图报错 报错的原因是什么?

package demo2;

import java.util.Arrays;

class Student implements Comparable<Student>{
    public String name;
    public int age;
    public Student(String name,int age) {
        this.name = name;
        this.age = age;
    }

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

    @Override
    public int compareTo(Student o) {
        // 用名字进行比较
        //return this.name.compareTo(o.name);
        // 用年龄进行比较
        return this.age - o.age;
    }

    public int my_compareTo(Student o){
        // 用名字进行比较
        //return this.name.compareTo(o.name);
        // 用年龄进行比较
        return this.age - o.age;
    }

}

public class Main {
    public static void main(String[] args) {
        Student student1 = new Student("a",20);
        Student student2 = new Student("c",19);
        Student student3 = new Student("b",21);
        Student[] arr = {student1,student2,student3};
        Arrays.sort(arr);
        System.out.println(Arrays.toString(arr));
    }

    /*public static void main1(String[] args) {
        Student student1 = new Student("abc",20);
        Student student2 = new Student("abd",19);

        if (student1.my_compareTo(student2) >= 0) {
            System.out.println("student1 >= student2");
        }else {
            System.out.println("student1 < student2");
        }
    }*/
}

也可以自己实现排序

package demo2;

import java.util.Arrays;

class Student implements Comparable<Student>{
    public String name;
    public int age;
    public Student(String name,int age) {
        this.name = name;
        this.age = age;
    }

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

    @Override
    public int compareTo(Student o) {
        // 用名字进行比较
        //return this.name.compareTo(o.name);
        // 用年龄进行比较
        return this.age - o.age;
    }

    public int my_compareTo(Student o){
        // 用名字进行比较
        //return this.name.compareTo(o.name);
        // 用年龄进行比较
        return this.age - o.age;
    }

}

public class Main {
    public static void my_sort(Comparable[] comparables) {
        for (int i = 0;i < comparables.length;i++) {
            for (int j = 0;j < comparables.length-i-1;j++) {
                if (comparables[j].compareTo(comparables[j+1]) > 0) {
                    Comparable tmp = comparables[j];
                    comparables[j] = comparables[j+1];
                    comparables[j+1] = tmp;
                }
            }
        }
    }
    public static void main(String[] args) {
        Student student1 = new Student("a",20);
        Student student2 = new Student("c",19);
        Student student3 = new Student("b",21);
        Comparable[] arr = {student1,student2,student3};
        /*Arrays.sort(arr);*/
        my_sort(arr);
        System.out.println(Arrays.toString(arr));
    }

    /*public static void main1(String[] args) {
        Student student1 = new Student("abc",20);
        Student student2 = new Student("abd",19);

        if (student1.my_compareTo(student2) >= 0) {
            System.out.println("student1 >= student2");
        }else {
            System.out.println("student1 < student2");
        }
    }*/
}

2.2 comparator 接口

comparable接口 有个不好的地方 如下图

comparator 接口可以很好解决这个问题 如下例

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

class Student implements Comparable<Student>{
    public String name;
    public int age;
    public Student(String name,int age) {
        this.name = name;
        this.age = age;
    }

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

    @Override
    public int compareTo(Student o) {
        // 用名字进行比较
        //return this.name.compareTo(o.name);
        // 用年龄进行比较
        return this.age - o.age;
    }
}

// 以年龄排序
class AgeComparator implements Comparator<Student> {
    @Override
    public int compare(Student o1, Student o2) {
        return o1.age - o2.age;
    }
}

// 以名字排序
class NameComparator implements Comparator<Student> {
    @Override
    public int compare(Student o1, Student o2) {
        return o1.name.compareTo(o2.name);
    }
}

public class Main {
    public static void main(String[] args) {
        Student student1 = new Student("a", 20);
        Student student2 = new Student("c", 19);
        Student student3 = new Student("b", 21);

        Student[] students = {student1, student2, student3};

        // 比较器的使用
        AgeComparator ageComparator = new AgeComparator();
        NameComparator nameComparator = new NameComparator();

        System.out.println(ageComparator.compare(student1, student2));
        System.out.println(nameComparator.compare(student1, student2));
        System.out.println("================================");

        // 传入比较器排序
        Arrays.sort(students,ageComparator);
        System.out.println(Arrays.toString(students));
        System.out.println("================================");
        Arrays.sort(students,nameComparator);
        System.out.println(Arrays.toString(students));
    }

}

2.3 Clonable接口和深浅拷贝

浅拷贝

问题引入:

报错的原因是什么 ? 如何实现拷贝 ?

报错原因有4个

class Person implements Cloneable {
    public String name;

    public Person(String name) {
        this.name = name;
    }

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

public class Main {
    public static void main(String[] args) throws CloneNotSupportedException{
        Person person1 = new Person("a");
        Person person2 = (Person) person1.clone();
        System.out.println(person2.name);
    }
}

深拷贝

什么是深拷贝 ? 如何实现一个深拷贝 ?

package test;

class Identity implements Cloneable {
    public int id = 1;

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

class Person implements Cloneable {
    public String name;
    public Identity identity;

    public Person(String name) {
        this.name = name;
        this.identity = new Identity();
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Person tmp = (Person) super.clone();
        tmp.identity = (Identity) this.identity.clone();
        return (Object) tmp;
    }
}

public class Main {
    public static void main(String[] args) throws CloneNotSupportedException{
        Person person1 = new Person("a");
        Person person2 = (Person) person1.clone();
        System.out.println("修改之前:  " + person1.identity.id);
        System.out.println("修改之前: " + person2.identity.id);
        System.out.println("=============================");
        person2.identity.id = 2;
        System.out.println("修改之后:  " + person1.identity.id);
        System.out.println("修改之后: " + person2.identity.id);
    }
    public static void main1(String[] args) throws CloneNotSupportedException{
        Person person1 = new Person("a");
        Person person2 = (Person) person1.clone();
        System.out.println(person2.name);
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值