接口的学习与总结

1.概念

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


2.语法规则

interface IShape{
    String name = "张三";
    //1.public static String name = "张三";
    //2.public static final String name = "张三";
    //上面3条语句是相同的

    public abstract void draw();
    //void draw(); //--》和上面语句相同,默认为 public abstract

    /*public void eat() { //这是错误的表示
        System.out.println("这是错误的");
    }*/

    default public void func() {
        System.out.println("利用default实现具体的方法");
    }

	public static void function() {
        System.out.println("利用static实现具体的方法");
    }

    /*public IShape() { //接口当中不存在构造器

    }*/
}

public class Test {
    public static void main(String[] args) {
        //IShape ishape = new IShape(); //不能被实例化
    }
}
使用关键字interface定义接口
不能被实例化
可以定义成员变量,但需要进行赋值(因为默认为public static final)
接口当中的方法不能有方法体,只能表示为抽象形式
接口当中的方法,默认为public abstract
如果一定要实现具体的方法(方法体),可以利用default或者static
接口当中不能有构造方法

提示:

  • 创建接口时, 接口的命名一般以大写字母 I 开头
  • 接口的命名一般使用 “形容词” 词性的单词
  • 阿里编码规范中约定, 接口中的方法和属性不要加任何修饰符号, 保持代码的简洁性

接口与抽象类的相同与不同

在这里插入图片描述


3.接口使用

接口不能直接使用,必须要有一个"实现类"来"实现"该接口,实现接口中的所有抽象方法。

class Circle implements IShape {
    @Override
    public void draw() {
        
    }
}

注意:子类和父类之间是extends 继承关系,类与接口之间是implements 实现关系


4.接口特性

4.1接口类型是一种引用类型,但是不能new接口对象

public interface IUSB {
    void openDevice();
    void closeDevice();

    public static void main(String[] args) {
        //IUSB iusb = new IUSB(); //报错
    }
}

4.2接口中每一个方法都是public的抽象方法, 即接口中的方法会被隐式的指定为 public abstract(只能是public abstract,其他修饰符都会报错)

public interface IUSB {
    void openDevice();
    void closeDevice();

    //private void eat(); //报错
}

4.3接口中的方法是不能在接口中实现的,只能由实现接口的类来实现

public interface IUSB {
    void openDevice();
    void closeDevice();

    /*void eat() {// 报错,如果要实现可以加default或static
        System.out.println(""); 
    }*/

}

4.4重写接口中方法时,不能使用默认的访问权限

public interface IUSB {
    void openDevice();
    void closeDevice();
    

}

class A implements IUSB {
    @Override
    public void openDevice() {
        
    }

    @Override
    /*void closeDevice() {//报错
        
    }*/
    
}

这是因为重写时,子类的访问权限要>=父类的访问权限


4.5接口中不能有静态代码块和构造方法

public interface IUSB {
    void openDevice();
    void closeDevice();

    /*static{
        //报错
    }*/
}

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

public interface IUSB {
    void openDevice();
    void closeDevice();

}

abstract class A implements IUSB {
    @Override
    public void openDevice() {
        
    }
    
}

接口虽然不是类,但是接口编译完成后字节码文件的后缀格式也是.class

两个不同的接口具有相同的方法名

interface A {
    void func();
}

interface B {
    void func();
}

class C implements A, B {
    @Override
    public void func() {
        System.out.println("CCCCCC");
    }
}

编译器在这里不会报错,但是会把这两个相同的方法看成是一种方法


5.接口之间的继承

interface A {
    void funa();
}

interface B {
    void funb();
}

interface C extends A, B {
    void func();
}

这段代码表示接口C不仅具有func这个功能,还具有funafunb这两个功能

接口间的继承相当于把多个接口合并在一起


6.接口使用实例

我们先来看一段代码

public class Test {
    public static void main(String[] args) {
        int[] arr = {1,3,8,5,2,9};
        Arrays.sort(arr);
        System.out.println(Arrays.toString(arr));
    }
}

通过Arrays.sort()可以给数组进行排序,然后输出一个有序的“字符串”数组

当整型数组变成学生型的还能够用这种方法进行排序吗?
代码如下:

class Student {
    public String name;
    public int age;
    public int score;
	//带有3个参数的构造方法
    public Student(String name, int age, int score) {
        this.name = name;
        this.age = age;
        this.score = score;
    }
    
}

public class Test {

    public static void main(String[] args) {
        Student[] students = new Student[3];
        students[0] = new Student("张三",8,75);
        students[1] = new Student("高俅",12,63);
        students[2] = new Student("小阁老",58,87);
        
        Arrays.sort(students);
        System.out.println(Arrays.toString(students));
    }
}

答案是不行的
因为我们没有给定一个规则进行排序(不知道是按照姓名,年龄还是成绩进行排序)

在这里插入图片描述

我们可以在类名这添加implements Comparable<类名>

在这里插入图片描述
利用cmopareTO这个方法指定比较的规则,然后给数组进行排序

在这里插入图片描述

按照年龄比较

此处的this指代的是谁调用的这个方法

在这里插入图片描述
这里指的就是students[0]

在这里插入图片描述

我们可以看到,当换成this.name这里会报错,这是因为name是一个字符串

在这里插入图片描述
可以改写成这样

完整代码

class Student implements Comparable<Student>{


    public String name;
    public int age;
    public int score;
	//带有3个参数的构造方法
    public Student(String name, int age, int score) {
        this.name = name;
        this.age = age;
        this.score = score;
    }

    @Override
    public int compareTo(Student o) {
        if(this.name.compareTo(o.name) > 0) {//按照姓名比较
            return 1;
        }else if(this.name.compareTo(o.name) < 0) {
            return -1;
        }else {
            return 0;
        }
    }


    /*@Override
    public int compareTo(Student o) {//按照年龄比较
        if(this.age > o.age) {
            return 1;
        }else if(this.age < o.age) {
            return -1;
        }else {
            return 0;
        }
    }*/

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

public class Test {

    public static void main(String[] args) {
        Student[] students = new Student[3];
        students[0] = new Student("张三",8,75);
        students[1] = new Student("高俅",12,63);
        students[2] = new Student("小阁老",58,87);

        Arrays.sort(students);
        System.out.println(Arrays.toString(students));
        //System.out.println(students[0].compareTo(students[1]));
    }
}

注意: 对于 sort 方法来说, 需要传入的数组的每个对象都是 “可比较” 的, 需要具备 compareTo 这样的能力。 通过重写 compareTo 方法的方式, 就可以定义比较规则

这种比较的缺点:不灵活

如果按照年龄(姓名/成绩)进行比较,这样就被写死了,以后再修改就会非常不方便

  • 7
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值