我们知道一个有抽象方法的类是抽象类,而当一个类中全是抽象方法时,就可以定义为接口(interface)
- 接口命名通常以“I”开头;
- 接口中的方法默认有public abstract(所以可以省略);
- 接口中的变量默认有public static final(静态常量),因此可以通过接口名直接调用,例如:
public interface IMammal{
public abstract void move();
void sleep(); //默认有public abstract
int AGE = 20; //常量通常用大写字母
}
public class Test{
public static void main(String[] args) {
System.out.println(IMammal.AGE); //输出结果:20
}
}
- 不同于“类”与“类”之间继承时为单继承,一个接口可以继承多个其他接口;
- 抽象类虽不能创建对象,但可以构造方法,而接口中两者都不可以,例如:
interface IA{}
interface IB{}
public interface IMammal extends IA,IB{ //继承多个其他接口
/*
public IMammal(){} //这是错的×,接口中不可以构造方法
*/
}
- 同时接口中也不能定义具体方法,
【但从JDK8开始(之前的都不行),可以声明具体方法,但必须为static或default】
public interface IMammal {
/*
public void bite(){
System.out.println("正在咬..."); //这是错的×
}
*/
public static void eat(){
System.out.println("正在吃...");
}
public default void play(){
System.out.println("正在嬉戏...");
}
}
- 一个“类”继承“接口”时,要用implements,而不能用extends;
- 和接口的继承相同,一个类也可以继承多个接口;
- 一个类如果不实现接口中的所有抽象方法(即重写),则该类必须为抽象类;
- 一个类继承接口的同时,也就继承了接口中的常量,
例如:上面定义过的静态常量AGE,当一个类继承该接口时,也就可以通过该类的类名直接调用;
public class Cat implements IMammal,IA{
@Override
public void move(){
System.out.println("正在屋顶上飞奔...");
}
@Override
public void sleep(){
System.out.println("正在蜷缩着睡觉...");
}
}
public class Test{
public static void main(String[] args) {
System.out.println(Cat.AGE); //输出结果:20
}
}
需要注意的两点:
- 接口只能继承父接口(一个或多个),不能继承类(包括普通类和抽象类);
- 接口继承接口、类继承类 用extends,类继承接口 用implements。
总结一下抽象类与接口的区别:
抽象类 | 接口 | |
---|---|---|
关键字 | abstract | interface |
成员变量 | 可包含任意合法成员变量 | 只包含静态常量(默认public static final) |
构造方法 | 有构造方法 | 无构造方法 |
方法 | 可定义任意合法的方法 | JDK8之后(之前不可)可以通过static或default修饰声明具体方法 |
继承 | “类”与“类”之间只能是单继承(用extends),但一个类可以继承多个接口(用implements) | 一个接口可以继承多个父接口(用extends),但不能继承“类” |