你所要知道的关于接口的知识点

2023-01-12 18:52:57 浏览数 (1)

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第31天,点击查看活动详情

接口

什么是接口

在Java中,接口可以看成是:多个类的公共规范,接口是一种引用数据类型。

接口的特点

1、使用interface来修饰接口 2、接口的成员变量默认都是public static final修饰的,因为有final,所以要进行初始化赋值 3、接口的成员方法默认都是抽象方法【以后的类要进行重写抽象方法】,由public abstract 修饰 4、接口的普通成员方法一般是不能有具体的实现的,但是在前面加上default就可以加上具体实现【JDK8以后才有的】 5、接口中可以有静态的成员方法,但是不管是default还是静态的方法,都是public的 6、接口也不能进行实例化 7、类与接口之间使用implements关联,接口可以引用具体的实现类,也能实现向上转型 8、接口里面不能有代码块或者构造方法(都不能实例化,要构造方法干什么呢) 9、抽象类实现一个接口,可以在在前面加上abstract,就不用重写接口中的抽象方法,但是下面还是要写别的类,还是要重写抽象方法【重写抽象方法是逃不掉的】

代码语言:javascript复制
interface IShape{
    int COUNT=12;//接口的成员变量默认是public static final修饰的
    void func();//接口的成员方法默认是public abstract修饰的
    void func1();//接口的成员方法一般不具体实现

    default void func2() {  
        System.out.println("haha");
    }
    static void func3() {
        System.out.println("heihei");
    }
}
public class Test {
        //IShape iShape=new IShape();   err,接口也是不能实例化的

}

接口的具体应用

代码语言:javascript复制
interface IShape{   //interface修饰接口
    void draw();
}
class Rect implements IShape {   //使用implements来连接接口与具体的类,叫做实现
    @Override  //对抽象方法重写
    public void draw() {   //上面的draw方法是public,所以这里要想访问draw就必须要使用public(大于等于接口的访问修饰限定符)
        System.out.println("矩形");
    }
}
class  Circle implements IShape {   
    @Override  
    public void draw() {
        System.out.println("圆");
    }
}

public class Test {
    public static void drawMap(IShape shape){
        shape.draw();//动态绑定
    }
    public static void main(String[] args) {
        //IShape iShape=new IShape();//err,接口不能实例化
        IShape rect= new Rect();//向上转型
        drawMap(rect);
        IShape circle = new Circle();
        drawMap(circle);
        //不进行实例化
        /* drawMap(new Rect());
        drawMap(new Circle());*/

    }
}

多个接口的具体使用

代码语言:javascript复制
abstract class Animal{
    String name;
    int age;

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

     public abstract void eat();//吃
}

//如何实现跑的动作?
//首先,不是所有的动物都能跑,所以跑这个动作不能放在Animal里面,其次,要是再写一个跑的类,但是Java是不允许多继承的(一个子类继承两个父类)
//所以为了实现这样的灵活调用,就要用到多个接口
interface IRUNNING{  //跑步的接口
    void run();
}
interface   IFLYING{  //飞的接口
     void fly();
}

class Dog extends Animal implements IRUNNING {   //Dog这个类继承了Animal类并且实现了IRUNNING接口
    public Dog(String name, int age) {
        super(name, age);
    }

    @Override
    public void eat() {
        System.out.println(this.name   "正在吃狗粮");
    }

    @Override
    public void run() {
        System.out.println(this.name "正在四处跑");
    }
}

class Bird extends Animal implements IRUNNING,IFLYING{   //Bird类继承了Animal类并且实现了IRUNNING,IFLYING多个接口,而狗就没有飞这个功能/接口,所以使用接口十分灵活
    public Bird(String name, int age) {
        super(name, age);
    }

    @Override
    public void eat() {
        System.out.println(this.name "正在吃鸟粮");
    }

    @Override
    public void run() {
        System.out.println(this.name "正在用细细的腿跳着跑");
    }

    @Override
    public void fly() {
        System.out.println(this.name "准备起飞");
    }
}

public class test {
    public static void Run(IRUNNING irunning) {   //传过来的都已经实现了接口,所以可以成功
        irunning.run();
    }
    public static void main(String[] args) {
        Run(new Dog("旺财", 2));
        Run(new Bird("小鸟", 3));
    }
    //以下是多态的使用,可以对比一下
    public static void func(Animal animal) {
        animal.eat();
    public static void main1(String[] args) {
        func(new Dog("旺财", 2));
        func(new Bird("小鸟", 3));
    }
    }
}

继承是is-a的关系(子类父类包含关系),接口是XXX特性,十分灵活

接口的继承

接口可以继承别的接口,也是使用extends,实现代码的复用

代码语言:javascript复制
interface  IA{
    void func1();
}
interface IB{
    void func2();
}

//接口的继承---接口功能的拓展
//IC拥有IA和IB的功能
interface IC extends IA, IB{
    void func3();
}

class A implements IC{

    @Override
    public void func1() {

    }

    @Override
    public void func2() {

    }

    @Override
    public void func3() {

    }
}
public class test {

}

几种常用的接口

1、比较自定义类型的大小 / 排序(Comparable接口)

注意:实现接口后面还要加上<自定义类名>

代码语言:javascript复制
//比较大小
class Student implements Comparable<Student>{ //此时会报错,直接alt enter,就可以重写compareTo方法
    String name;
    int age;
    double score;

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

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

    @Override
    public int compareTo(Student o) {  //重写compareTo方法
        /*if (this.age > o.age) {
            return 1;
        } else if (this.age == o.age) {
            return 0;
        } else {
            return -1;
        }
*/
        return this.age-o.age;//o就是传的参数,谁调用compareTo谁就是this
        //两种代码效果是一样的,按照年龄比较大小
    }
}
public class test {
    public static void main(String[] args) {
        Student student1 = new Student("zhangsan", 32, 29.0);
        Student student2 = new Student("lisi", 20, 1.2);
        if (student1.compareTo(student2) > 0) {
            System.out.println("student1>student2");
        }
    }
}
代码语言:javascript复制
//排序
import java.util.Arrays;
class Student implements Comparable<Student>{
    String name;
    int age;
    double score;

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

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

    @Override
    public int compareTo(Student o) {  //重写
        return this.age-o.age;//o就是传的参数,谁调用compareTo谁就是this
        //要是想要改为降序就调换一下减的顺序
    }
}
public class test {
    public static void main(String[] args) {
        Student[]  student= new Student[3]; //定义Student类型的数组
        student[0] = new Student("zhangsan", 32, 29.0);
        student[1] = new Student("lisi", 20, 1.2);
        student[2] = new Student("wangwu", 52, 89);
        System.out.println("排序前" Arrays.toString(student));
        Arrays.sort(student);//要是不写Comparable接口就不知道是按照什么进行排序的
        System.out.println("排序后" Arrays.toString(student));//升序打印
    }
}

但是上面使用Comparable接口,就将比较/排序的规则定死了,已经加入到了Student类里面,后期就会不方便改

此时既可以使用Comparator接口

2、Comparator接口(比较器)
代码语言:javascript复制
import java.util.Comparator;

//比较大小
class Student {
    String name;
    int age;
    double score;

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

    @Override
    public String toString() {
        return "Student{"  
                "name='"   name   '''  
                ", age="   age  
                ", 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);
    }
}

class NameComparator implements Comparator<Student> {  //定义一个名字比较器的类
    @Override
    public int  compare(Student o1, Student o2) {
        return o1.name.compareTo(o2.name);//compareTo的返回值是int
    }
}

public class test {
    public static void main(String[] args) {
        Student student1 = new Student("zhangsan", 32, 29.0);
        Student student2 = new Student("lisi", 20, 1.2);
        AgeComparator ageComparator = new AgeComparator();//实例化年龄比较器
        int ret=ageComparator.compare(student1, student2);
        System.out.println(ret);  
        
        
        ScoreComparator scoreComparator = new ScoreComparator();//实例化分数比较器
        int ret2 = scoreComparator.compare(student1, student2);
        System.out.println(ret2);
        
         NameComparator nameComparator = new NameComparator();//实例化名字比较器
        int ret3 = nameComparator.compare(student1, student2);
        System.out.println(ret3);
    }
    
    //年龄之差12
    //分数之差是27
    //名字的首字母相差14

使用比较器对数组元素进行排序

代码语言:javascript复制
import java.util.Arrays;
import java.util.Comparator;

class Student {
    String name;
    int age;
    double score;

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

    @Override
    public String toString() {
        return "Student{"  
                "name='"   name   '''  
                ", age="   age  
                ", 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);
    }
}

class NameComparator implements Comparator<Student> {
    @Override
    public int  compare(Student o1, Student o2) {
        return o1.name.compareTo(o2.name);//compareTo的返回值是int
    }
}

public class test {
    public static void main(String[] args) {
        Student[]  student= new Student[3];
        student[0] = new Student("zhangsan", 32, 29.0);
        student[1] = new Student("lisi", 20, 1.2);
        student[2] = new Student("wangwu", 52, 89);
        
        AgeComparator ageComparator = new AgeComparator();//实例化年龄比较器
        Arrays.sort(student, ageComparator);//Arrays.sort是可以重载的(既可以只放一个数组名,还能再放一个比较器对象)
        System.out.println(Arrays.toString(student));
        
        ScoreComparator scoreComparator = new ScoreComparator();
        Arrays.sort(student, scoreComparator);
        System.out.println(Arrays.toString(student));

        NameComparator nameComparator = new NameComparator();
        Arrays.sort(student, nameComparator);
        System.out.println(Arrays.toString(student));

    }
//[Student{name='lisi', age=20, score=1.2}, Student{name='zhangsan', age=32, score=29.0}, Student{name='wangwu', age=52, score=89.0}]
//    
//[Student{name='lisi', age=20, score=1.2}, Student{name='zhangsan', age=32, score=29.0}, Student{name='wangwu', age=52, score=89.0}]
//    
//[Student{name='lisi', age=20, score=1.2}, Student{name='wangwu', age=52, score=89.0}, Student{name='zhangsan', age=32, score=29.0}]

使用比较器不会涉及到自定义的类,想要按照什么比较就写一个专门的比较器,实例化 比较器来进行比较,所以写比较器是十分灵活的,十分好用

3、克隆当前对象(Cloneable接口)
代码语言:javascript复制
class Person implements Cloneable{ //Cloneable里面没有任何东西,是一个空接口/标记接口:说明当前类可以被克隆
    public int age;

    public Person(int age) {
        this.age = age;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {  //正式实现克隆  alt enter,选中clone即可
        //重写的是Object里面的clone方法(由C/C  写的,所以看不见)
        return super.clone();
    }

    @Override
    public String toString() {
        return "Person{"  
                "age="   age  
                '}';
    }

}
public class Test {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person = new Person(10);
        Person person2= (Person) person.clone();//要将Object类型的强转为Person
        System.out.println(person);
        System.out.println(person2);
    }
}

我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=39wzavdyvgg0g

0 人点赞