我们知道,在Java中一个类只能继承(extends)一个父类,但是一个类的实现可以包含多种多样的功能,仅仅通过继承一个类是不能实现用户需求的。所以Java引入了接口这个概念。我们可以通过实现(implements)多个接口,来丰富我们的类,让程序猿忘记类型, 有了接口之后,类的使用者就不必关注具体类型, 而只关注某个类是否具备某种能力。

  • Interface – 接口
            以下接口 IShape 被 Circle 类实现,实现时必须重写接口内的抽象方法,而后就可实现自己重新实现的接口。此外,interface IShape中的方法修饰符默认为public abstract。即完整的为public abstract void draw();此外一个类可以实现多个接口。
interface IShape {
	void draw();
}
class Circle implements IShape {
	@Override
	public void draw() {
		System.out.println("○");
	}
}
public class Test {
	public static void main(String[] args) {
		IShape shape = new Circle();
		shape.draw();
	}
}

编程规范提示:

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

注意:
1、使用 interface 定义一个接口 接口中的方法一定是抽象方法, 因此可以省略abstract
2、接口中的方法一定是 public,因此可以省略 public
3、Cycle 使用 implements 继承接口. 此时表达的含义不再是 "扩展(extends) ", 而是 “实现(implements)”.扩展指的是当前已经有一定的功能了, 进一步扩充功能.
实现指的是当前啥都没有, 需要从头构造出来。
4、在调用的时候同样可以创建一个接口的引用, 对应到一个子类的实例. 接口不能单独被实例化
5、接口中只能包含抽象方法. 对于字段来说, 接口中只能包含静态常量(final static).

  • 常用的接口实例
class Student {
private String name;
private int score;
public Student(String name, int score) {
this.name = name;
this.score = score;
}
@Override
public String toString() {
return "[" + this.name + ":" + this.score + "]";
}
}

Student[] students = new Student[] {
new Student("张三", 95),
new Student("李四", 96),
new Student("王五", 97),
new Student("赵六", 92),
};
  • Comparable

        对于上面的学生对象,若使用Arrays.sort(students);方法进行排序是不可行的,一个比整数复杂的对象是不能单单用这样一个函数进行排序的。我们需要额外制定规则,这样Comparable接口就派上了用场。我们指定Student类实现 Comparable 接口, 并实现其中的 compareTo 方法。此后在 sort 方法中会自动调用 compareTo 方法. compareTo 的参数是 Object , 其实传入的就是 Student 类型的对象.

@Override
public int compareTo(Object o) {
	Student s = (Student)o;
	if (this.score > s.score) {
		return -1;
	} else if (this.score < s.score) {
		return 1;
	} else {
		return 0;
	}
}
  • Comparator
          在类外写一个分数比较的接口实现Comparator接口,并重写Compare方法,实现对于student类中成员的分数排名。
public class ScoreComparator implements Comparator<Student2> {
    @Override
    public int compare(Student2 o1, Student2 o2) {
        if(o1.score > o2.score) {
            return 1;
        }else if(o1.score == o2.score) {
            return 0;
        }else {
            return -1;
        }    
    }
}
  • Clonable
          Object 类中存在一个 clone 方法, 调用这个方法可以创建一个对象的 “拷贝”. 但是要想合法调用 clone 方法, 必须要先实现 Clonable 接口, 否则就会抛出 CloneNotSupportedException 异常.
class Money implements Cloneable{
    public double money = 12.8;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
class Person implements Cloneable{
    public String name;

    public Money m = new Money();

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

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

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Person person2 = (Person)super.clone();
        person2.m = (Money) this.m.clone();
        return person2;
    }
}
public class TestDemo3 {


    public static void main(String[] args) throws CloneNotSupportedException {
        Person person1 = new Person("张三");
        Person person2 = (Person)person1.clone();
        System.out.println(person1.m.money);
        System.out.println(person2.m.money);
        person2.m.money = 99.99;
        System.out.println(person1.m.money);
        System.out.println(person2.m.money);
    }