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这个功能,还具有funa和funb这两个功能
接口间的继承相当于把多个接口合并在一起
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 方法的方式, 就可以定义比较规则
这种比较的缺点:不灵活
如果按照年龄(姓名/成绩)进行比较,这样就被写死了,以后再修改就会非常不方便