Java基础笔记12-接口
1.接口定义
-
概念:当抽象类中的方法都是抽象方法时,建议将该类转换为接口。
-
关键字:interface
- 接口通常以interface来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。
-
/** * 定义一个Fruits接口,接口名建议以I开头 */ interface IFruits{ /** * 颜色 */ public abstract void color(); /** * 类型 */ void type();//接口内方法的修饰符默认为public abstract ,可不写 }
2.接口的特性
-
接口是隐式抽象的,当声明一个接口的时候,不必使用abstract关键字。
-
接口内的方法都是抽象方法,变量都是常量。(1.8及之后接口可以定义默认方法)
- 接口中的方法一定是抽象方法,变量一定是静态的常量
- 注意:接口中的常量默认修饰符是public static,方法的默认修饰符是public abstract
-
接口内方法的修饰符默认为public abstract ,可不写,但建议写上。
-
接口存在的意义主要是用于定义规范规则,没有具体实现,仅是为了定义数据层的所有功能。
-
接口耦合性低,规则性强,扩展性好,可以实现多继承。
-
接口中的方法都是公有的。
2.1.接口与抽象类的区别
- 接口中都是抽象方法,抽象类中还可以有普通方法。
- 抽象类中可以有构造器,接口中没有。
- 抽象类中定义的是公共的功能,接口中定义的额外的功能。
- 抽象类中的方法可以有方法体,就是能实现方法的具体功能,但是接口中的方法不行。
- 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是 public static final 类型的。
- 接口中不能含有静态代码块以及静态方法(用 static 修饰的方法),而抽象类是可以有静态代码块和静态方法。
- 一个类只能继承一个抽象类,而一个类却可以实现多个接口。
2.2.接口与类的区别
- 接口不能用于实例化对象。
- 接口没有构造方法。
- 接口中所有的方法必须是抽象方法。
- 接口不能包含成员变量,除了 static 和 final 变量。
- 接口不是被类继承了,而是要被类实现。
- 接口支持多继承。
3.接口的实现
-
关键字:implements
-
在类声明中,Implements关键字放在class声明后面。
-
当类实现接口的时候,类要实现接口中所有的方法。否则,类必须声明为抽象的类。
-
重写接口中声明的方法时,需要注意以下规则:
- 类在实现接口的方法时,不能抛出强制性异常,只能在接口中,或者继承接口的抽象类中抛出该强制性异常。
- 类在重写方法时要保持一致的方法名,并且应该保持相同或者相兼容的返回值类型。
- 如果实现接口的类是抽象类,那么就没必要实现该接口的方法。
-
在实现接口的时候,也要注意一些规则:
- 一个类可以同时实现多个接口。
- 一个类只能继承一个类,但是能实现多个接口。
- 一个接口能继承另一个接口,这和类之间的继承比较相似。
4.接口的多继承
- 一个接口能继承另一个接口,和类之间的继承方式比较相似。接口的继承使用extends关键字,子接口继承父接口的方法。
- 普通类中是不允许多继承的,因为会出现调用不明确的问题,接口和接口之间可以多继承
5.代码举例
public class InterfaceDeme {
public static void main(String[] args) {
AppleTree appletree = new AppleTree();
System.out.println(appletree.name);
appletree.type();
appletree.leaf();
appletree.trunk();
appletree.seed();
}
}
/**
* 定义一个植物IBotany接口
*/
interface IBotany{
//叶子
public abstract void leaf();
//枝干
public abstract void trunk();
}
/*
* 蔷薇科植物
*/
interface IRosaceaePlants{
//类型
public abstract void type();
}
/**
* 定义一个IFruits接口,使用多继承
*/
interface IFruits extends IBotany,IRosaceaePlants {
//种子
public abstract void seed();
}
class AppleTree implements IFruits{
public String name = "苹果树";
@Override
public void leaf() {
System.out.println("叶子,春天发芽,夏天是绿色,秋天变黄落叶");
}
@Override
public void trunk() {
System.out.println("多年生乔木,枝干可长到十几米高,但果园里一般不超过五米");
}
@Override
public void seed() {
System.out.println("有种子,在果肉中间");
}
@Override
public void type() {
System.out.println("蔷薇科植物");
}
}
输出:
苹果树
蔷薇科植物
叶子,春天发芽,夏天是绿色,秋天变黄落叶
多年生乔木,枝干可长到十几米高
有种子,在果肉中间
-
上部代码实例中,IFruits接口使用了多继承来继承IBotany,IRosaceaePlants接口,因接口内的方法都是抽象方法,没有方法体,之后使用的时候都需要重写,也就不存在调用不明确的问题。
-
class AppleTree implements IFruits 通过implements 来实现接口中的方法, implements与继承类似,用于继承接口。