类和对象进阶 - 接口

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);
}
}

 

posted @   qyx1  阅读(16)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示