我们知道,在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();
}
}
编程规范提示:
- 我们创建接口的时候, 接口的命名一般以大写字母 I 开头.
- 接口的命名一般使用 “形容词” 词性的单词.
- 阿里编码规范中约定, 接口中的方法和属性不要加任何修饰符号, 保持代码的简洁性
注意:
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);
}