1.语法规则
接口是抽象类的更进一步. 抽象类中还可以包含非抽象方法, 和字段。
而接口中包含的方法都是抽象方法, 字段只能包含静态常量.
interface IShape {
/*public abstract */ void draw();
/*public static final*/ int num = 10;
}
提示:
- public, static, final 的关键字都可以省略. 省略后的 num 仍然表示 public 的静态常量.
- 我们创建接口的时候, 接口的命名一般以大写字母 I 开头.
- 接口的命名一般使用 “形容词” 词性的单词.
- 阿里编码规范中约定, 接口中的方法和属性不要加任何修饰符号, 保持代码的简洁性.
代码示例
//使用 interface 定义一个接口
interface IShape{
//接口中的方法一定是抽象方法, 因此可以省略 abstract .
//接口中的方法一定是 public, 因此可以省略 public
void draw();
}
//Cycle 使用 implements 继承接口. 此时表达的含义不再是 "扩展", 而是 "实现"
class Cycle implements IShape{
@override
public void draw(){
system.out.println("o");
}
}
public class Test{
public static void main(String[] args){
//在调用的时候同样可以创建一个接口的引用, 对应到一个子类的实例.
//接口不能单独被实例化.
IShape shape = new Rect();
shape.draw();
}
}
- 使用 interface 定义一个接口
- 接口中的方法一定是抽象方法, 因此可以省略 abstract
- 接口中的方法一定是 public, 因此可以省略 public
- Cycle 使用 implements 继承接口. 此时表达的含义不再是 “扩展”, 而是 “实现”
- 在调用的时候同样可以创建一个接口的引用, 对应到一个子类的实例.
- 接口不能单独被实例化.
2.实现多个接口
有的时候我们需要让一个类同时继承自多个父类. 这件事情在有些编程语言通过 多继承 的方式来实现的.
Java 中只支持单继承, 一个类只能 extends 一个父类. 但是可以同时实现多个接口, 也能达到多继承类似的效果.
代码示例
动物类
class Animal {
protected String name;
public Animal(String name) {
this.name = name;
}
}
提供一组接口, 分别表示 “会飞的”, “会跑的”, “会游泳的”.
interface IFlying {
void fly();
}
interface IRunning {
void run();
}
interface ISwimming {
void swim();
}
创建几个具体的动物
会跑的猫咪
class Cat extends Animal implements IRunning {
public Cat(String name) {
super(name);
}
@Override
public void run() {
System.out.println(this.name + "正在用四条腿跑");
}
}
会游的鱼
class Fish extends Animal implements ISwimming {
public Fish(String name) {
super(name);
}
@Override
public void swim() {
System.out.println(this.name + "正在用尾巴游泳");
}
}
水陆空三栖的鸭子
class Duck extends Animal implements IRunning, ISwimming, IFlying {
public Duck(String name) {
super(name);
}
@Override
public void fly() {
System.out.println(this.name + "正在用翅膀飞");
}
@Override
public void run() {
System.out.println(this.name + "正在用两条腿跑");
}
@Override
public void swim() {
System.out.println(this.name + "正在漂在水上");
}
}
多态的好处:让程序猿忘记类型. 有了接口之后, 类的使用者就不必关注具体类型, 而
只关注某个类是否具备某种能力.
3.接口使用示例
两个学生对象的大小关系怎么确定? 需要我们额外指定.让我们的 Student 类实现 Comparable 接口, 并实现其中的 compareTo 方法
class Student implements Comparable {
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 + "]";
}
@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;
}
}
}
4.接口间的继承
接口可以继承一个接口, 达到复用的效果,相当于把接口合并. 使用 extends 关键字.
interface IRunning {
void run();
}
interface ISwimming {
void swim();
}
// 两栖的动物, 既能跑, 也能游
interface IAmphibious extends IRunning, ISwimming {
}
class Frog implements IAmphibious {
...
}
通过接口继承创建一个新的接口 IAmphibious 表示 “两栖的”. 此时实现接口创建的 Frog 类, 就继续要实现 run 方法,也需要实现 swim 方法.
5.Clonable 接口和深拷贝
6.总结
接口抽象类区别
抽象类中可以包含普通方法和普通字段, 可以被子类直接使用(不必重写),
接口中不能包含普通方法, 子类必须重写所有的抽象方法.
No | 区别 | 抽象类(abstract) | 接口(interface) |
---|---|---|---|
1 | 结构组成 | 普通类+抽象方法 | 抽象方法+全局变量 |
2 | 权限 | 各种权限 | public |
3 | 子类使用 | extends继承抽象类 | implements实现接口 |
4 | 关系 | 一个抽象类可以实现多个接口 | 接口不能继承抽象类但是可以用extends继承多个父接口 |
5 | 子类限制 | 一个子类只能继承一个抽象类 | 一个子类可以实现多个接口 |
代码实例
例如:Animal 中包含一个 name 这样的属性, 这个属性在任何子类中都是存在的. 因此此
处的 Animal 只能作为一个抽象类, 而不应该成为一个接口.
class Animal {
protected String name;
public Animal(String name) {
this.name = name;
}
}