一、接口的定义
1.1 什么是接口
Java中这个接口的概念到底是什么:
首先接口这个词在日常生活中代表的是两个事物之间的连接处,在现实生活中我们有个东西叫USB接口,下图展示的就是电脑的USB接口,
图中红色箭头所指就是USB接口 ,它可以接入:U盘、鼠标、键盘等具有明确功能的外部设备,还有很多其他的设备,这些设备所能实现的功能也不相同,把不一样的标准通过接口进行统一的接入,这就是接口的作用
下面用较为官方的说法来介绍什么是接口:
- 接口(interface),在Java编程中是一个抽象类型,是抽象方法的集合(抽象方法:只有方法声明没有方法实现),接口通常以interface来声明,一个类通过继承接口的方式,从而继承接口的抽象方法
- 接口并不是类,编写接口的方式却和类很相似,但是他们属于不同的概念,
- 类的三大要素是属性、方法、构造器,用来描述对象的属性和状态,但接口则包含要实现类的方法
- 接口无法被实例化,但必须被实现,一个实现接口的类,必须实现接口内所描述的所有方法
1.2 接口与类的对比
先进行举例,再进行说明:
注意:接口中的成员属性默认为public static final修饰,成员方法是public abstract修饰,(不写就是使用默认修饰)
//定义接口需要使用关键字interface
public interface A {
public static final Integer age = 11; //定义全局静态常量(public static final)
public abstract void print(); //定义抽象方法、
default public void otherprint() { //定义可以带方法体的默认方法
System.out.println("默认方法");
}
}
接口与类的相似点:
- 一个接口可以有多个方法(抽象方法),或是default修饰带方法体的默认方法
- 接口文件保存在 .java结尾的文件夹中,文件名使用接口名
接口与类的区别:
- 接口不能用于实例化对象
- 接口没有构造方法
- 接口中的所有方法必须是抽象方法,但在Java8之后 接口可以使用default关键字修饰的非抽象方法(可带方法体)
- 接口只能包含public static final修饰的全局静态常量(可以忽略不写)
- 接口不是要被类继承,而是要被类实现(使用implements关键字实现接口)
- 接口支持多继承
接口特性:
- 接口中每一个方法都是隐式抽象的,接口中的抽象方法会被隐式指定为public abstract(只能是public abstract,其他修饰符会报错,但现在还有一种用default 修饰的带方法体的默认方法也可以)
- 接口中可以含有变量,但只能是public static final修饰的(只能是public修饰,private修饰会报错)
- 接口中的方法是不能在接口中实现的,只能在实现接口的类中实现
- 接口中的方法都是公有的
抽象类与接口的区别:
- 抽象类的方法可以有方法体,就是能实现方法的具体功能,但是接口中的方法不能有方法体
- 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final修饰的
- 接口中不能含有静态代码块和静态方法(用static修饰的方法),而抽象类中可以有静态代码块和静态方法
- 一个类只能继承一个抽象类(不能多继承),而一个类可以实现多个接口(接口的实现满足多继承)
- 注:JDK1.8之后,接口中可以有静态方法和方法体(用default修饰)
- 注:JDK1.8之后,接口中方法允许包含具体实现的方法,该方法称之为”默认方法",默认方法使用default修饰,
- 注:JDK1.9之后,允许将方法定义为private,使得某些复用的代码不会将代码暴露出去
1.3 接口的声明
接口的声明格式如下:
[访问符] interface 接口名称 [extends 其他的接口名] {
// 声明变量
// 抽象方法
}
在IDEA中创建接口的步骤
- 选择a这个包右键New----选择Java Class
- 选择Interface接口,输入接口名称例如"Animal"
这样的Animal就是一个接口了,在其中填入相应的变量和方法即可
1.4 接口的实现
- 当类实现接口的时候,子类必须覆盖掉接口中所有的抽象方法,子类才能实例化,如果没有,该类必须声明为抽象类
- 类使用implements关键字实现接口,实现类使用Impl结尾,即接口名称+Impl
接口的实现类声明格式如下:
【访问符】 class 实现类 implements 【接口1,接口2,接口3等等】(因为接口支持多继承)
接口实现的案例:
篮球运动员和教练
乒乓球运动员和教练
现在篮球运动员和教练要出国访问,需要学习英语
分析出哪些是类、哪些是抽象类、哪些是接口
步骤如下:
- 定义People类,声明变量和方法
public class People {
//定义变量,姓名、年龄、性别
public String name;
public Integer age;
public String sex;
//定义吃饭方法
public void eat(){
System.out.println("吃饭");
}
//定义睡觉方法
public void sleep(){
System.out.println("睡觉");
}
//无参构造
public People() {
}
//有参构造
public People(String name, Integer age, String sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
}
- 定义抽象类运动员Player,声明抽象方法学习study
//运动员Player这个抽象类继承父类People
public abstract class Player extends People {
//定义抽象方法学习(抽象方法没有方法体,即没有具体的实现)
public abstract void study();
}
- 定义抽象类教练Coach,声明抽象方法教学teach
//教练Coach这个抽象类继承父类People
public abstract class Coach extends People{
//定义抽象方法教学(抽象方法中没有方法体,即没有具体的方法实现)
public abstract void teach();
}
- 定义接口说英语,在其中声明抽象方法speak
//定义接口说英语
public interface SpeakEnglish {
//接口中的抽象方法speak(抽象方法没有方法体,即没有具体方法的实现)
public abstract void speak();
}
- 定义抽象类Player的实现类:乒乓球运动员,并重写父类Player中的方法
//乒乓球运动员PingpangPlayer这个类继承于抽象类Player
public class PingpangPlayer extends Player{
//注解 @Override是为了方便重写
//重写抽象类Player中的方法
@Override
public void study() {
System.out.println("乒乓球运动员,练习抽球");
}
}
- 定义抽象类Coach的实现类:乒乓球教练,并重写父类Coach中的方法
//乒乓球教练PingpangCoach这个类继承于抽象类Coach
public class PingpangCoach extends Coach{
//注解 @Override 是为了方便重写
//重写抽象类Coach中的方法
@Override
public void teach() {
System.out.println("乒乓球教练,教抽球");
}
}
- 定义运动员实现类和说英语接口实现类:篮球运动员类,重写抽象类中的方法,接口中的方法
//实现类BasketBallPlayer继承Player,并实现了接口SpeakEnglish
public class BasketBallPlayer extends Player implements SpeakEnglish {
//注解 @Override 是为了方便重写
//重写抽象类中的方法
@Override
public void study() {
System.out.println("篮球运动员,学习扣篮");
}
//注解 @Override 是为了方便重写
//重写接口SpeakEnglish中的方法
@Override
public void speak() {
System.out.println("学习说英语");
}
}
- 定义教练的实现类和说英语接口实现类:篮球教练,重写抽象类中的方法,接口中的方法
//实现类BasketBallCoach继承抽象类Coach,并实现了接口SpeakEnglish
public class BasketBallCoach extends Coach implements SpeakEnglish{
//注解@Override是为了方便重写
//重写抽象类中的方法
@Override
public void teach() {
System.out.println("篮球运动员,教扣篮");
}
//注解@Override是为了方便重写
//重写抽象类中的方法
@Override
public void speak() {
System.out.println("学说英语");
}
}
- 启动项:
public class DemoApplication {
public static void main(String[] args) {
//创建篮球运动员对象
BasketBallPlayer bbp = new BasketBallPlayer();
bbp.name = "姚明";
bbp.age = 11;
bbp.sex = "男";
bbp.eat();
bbp.sleep();
bbp.study();
bbp.speak();
System.out.println("----------------------------------------");
//创建乒乓球教练对象
PingpangCoach ppc = new PingpangCoach();
ppc.name = "刘国伟";
ppc.age = 11;
ppc.sex = "女";
ppc.eat();
ppc.sleep();
ppc.teach();
// ppc.speak(); 乒乓球教练没有speak()
}
}
- 控制台打印输出
吃饭
睡觉
篮球运动员,学习扣篮
学习说英语
----------------------------------------
吃饭
睡觉
乒乓球教练,教抽球
Process finished with exit code 0
在实现接口时,也要有所注意
- 一个类可以实现多个接口 【class 类 implements 接口1,接口2,】
- 一个类只能实现一个类(只能单继承,但可以多重继承,即从 太爷爷到爷爷到爸爸到儿子),
- 一个类可以实现多个接口(1 中的示范)
- 一个接口可以继承另一个接口,这跟类的继承有点像
1.5 接口的继承
一个接口可以继承另外一个接口,这跟类的继承相似,接口与接口之间的继承也使用extends关键字,子接口继承父接口的方法
- 定义接口Sport
public interface Sport {
public void setHomeTeam(String name);
public void setVisitingTeam(String name);
}
- 定义接口FooterBall继承父类接口Sport
//接口FooterBall继承父接口Sport
public interface FooterBall extends Sport{
public void homeTeamScored(int points);
public void visitingTeamScored(int points);
public void endOfQuarter(int quarter);
}
- 定义接口Hockey继承父类接口Sport
public interface Hockey {
public void homeGoalScored();
public void visitingGoalScored();
public void endOfPeriod(int period);
public void overtimePeriod(int ot);
}
子接口Hockey已经定义了4个方法,从父类继承了2个方法,所以要实现子接口Hockey需要重写6个方法,
子接口FooterBall已经定义了2个方法,从父类继承了2个方法,所以要实现子接口FooterBall需要重写4个方法,
1.6 接口的多继承
在Java中,类的多继承时不合法的,但接口的多继承是被允许的
在接口的多继承中extends关键字只需要使用一次,在其后跟着其他继承接口(用逗号隔开)
public interface Hockey extends Sport, Event