最接近接口定义的、最形象的、现实生活中存在的东西就是——USB接口。比如我们的鼠标、键盘、U盘,有的耳机,灯,冲充电设备都统统连接在USB接口上来使用,但是我们的鼠标,键盘,根本都是不一样的东西,里面的构造功能都大相径庭。于是一个能够提供各种功能的接口出现了。来保证他们能够一起为计算机服务。接口的概念在生活中就是某些组织或者企业等制定的一种约定或者标准。就像USB接口一样,鼠标制造商和键盘制造商在各自制造鼠标键盘的时候,都遵从同一个接口标准,都可以通过USB接口插在电脑上使用;不局限于真的像接口这种字面意义的插口,像菜谱一样,也是一种接口,比如这道菜叫做宫保鸡丁,好,所有厨师都做宫保鸡丁,这样顾客来吃饭的时候,就直接点菜:宫保鸡丁。而不会过来说,把鸡肉,黄瓜,胡萝卜给我炒一盘菜。当然各个厨师有自己的想法和特色,都叫宫保鸡丁,但是味道和做法也会不相同。像说的USB接口和菜谱这种,都是接口的概念。
接口
JAVA中的接口
接口是一种特殊的类,它只有方法的形式描述,没有任何实际内容,不包含任何实例变量。类的继承叫做继承,接口的继承叫做实现
接口的特点
- 接口不能被实例化
- 接口用来被类实现
- 接口中可以定义属性和方法
- 接口中的所有属性 默认的修饰符是 public static final,所以定义时必须赋值。
- 接口中的所有方法 默认的修饰符是 public abstract
- 接口不能直接进行实例化: 定义实现类,实现接口,类创建对象,对象调用方法
- 接口的子类
- 实现接口中所有的方法,成为实现类,可以创建对象。
- 未实现接口所有的方法,成为抽象类,不能创建对象。
- 接口没有构造方法
代码示例:
interface MyInter {
//private int id; 接口中不能定义普通的成员变量
public static final double PI = 3.14; //接口中定义的变量只能是常量
public abstract void fun1();
public void fun2();
void fun3(); //都是一样的,前面默认的都是public abstract
}
其中的关键字:interface
我们再来创建一个类来实现这个接口:
当我们还没有对接口里面的方法进行重写时,eclipse会报错,提示让去创建重写的方法。创建重写方法之后:
interface MyInter {
//private int id; 接口中不能定义普通的成员变量
public static final double PI = 3.14; //接口中定义的变量只能是常量
public abstract void fun1();
public void fun2();
void fun3(); //都是一样的,前面默认的都是public abstract
}
class MyI implements MyInter{
@Override
public void fun1() {
// TODO Auto-generated method stub
}
@Override
public void fun2() {
// TODO Auto-generated method stub
}
@Override
public void fun3() {
// TODO Auto-generated method stub
}
}
实践是检验真理的唯一标准。我们来做个小Demo练习一下:
题目:
假设一个学校接待方面的程序,招待不同身份的人的食宿问题,其对应规则如下:
身份 | 食 | 宿 |
学生 | 食堂 | 宿舍 |
教师 | 教师食堂 | 学校公寓 |
学生家长 | 招待所 | 招待所 |
理论上,当然可以对每个不同身份的人各定义一个对应的类,并实现各自的方法,但是观察这些类,可以归纳出其有一个共同的模板,即“人”的“食、宿”问题。这时候,就可以发挥接口的功能了。
代码示例:
public class 学生家长老师 {
public static void main(String[] args) {
Student s = new Student();
life(s);
Teacher t = new Teacher();
life(t);
Parent p = new Parent();
life(p);
}
public static void life(Person p) {
p.eat();
p.sleep();
}
}
interface Person{
public void eat();
public void sleep();
}
class Student implements Person{
public void eat() {
System.out.println("在食堂吃饭");
}
public void sleep() {
System.out.println("在宿舍睡觉");
}
}
class Teacher implements Person{
public void eat() {
System.out.println("在教室食堂吃饭");
}
public void sleep() {
System.out.println("在学校公寓睡觉");
}
}
class Parent implements Person{
public void eat() {
System.out.println("在招待所吃饭");
}
public void sleep() {
System.out.println("在招待所睡觉");
}
}
我们就创建了这样的一个结构。大家做着相同的事,但是各做各的,互不干扰。
结果输出:
在食堂吃饭
在宿舍睡觉
在教室食堂吃饭
在学校公寓睡觉
在招待所吃饭
在招待所睡觉
练习2:
需求说明:
电视、风扇、冰箱等各种电器要想工作必须提供电源,使用接口模拟电器获得电源后进行工作。
分析:
定义电源插座的接口(SocketInterface),具有供电的能力。getElectric()
定义类:电视类(TV)、风扇类(Fan)、冰箱类(Icebox),分别实现电源插座接口。
定义测试类,包含电器开始工作的方法,参数为电器对象(接口的引用指向实现类的对象,实现多态)。
代码示例:
public class 电器 {
public static void main(String[] args) {
TV tv = new TV();
work(tv);
Icebox ib = new Icebox();
work(ib);
Fan fan = new Fan();
work(fan);
}
public static void work(SocketInterface skt){
skt.getElectric();
}
}
interface SocketInterface{
void getElectric(); // 通电方法
}
class TV implements SocketInterface{
public void work(){
System.out.println("播放节目");
}
public void getElectric() {
System.out.println("电视通电后开始工作");
work();
}
}
class Icebox implements SocketInterface{
public void work(){
System.out.println("冻东西");
}
public void getElectric() {
System.out.println("冰箱通电后开始工作");
work();
}
}
class Fan implements SocketInterface{
public void work(){
System.out.println("吹。。。。。");
}
public void getElectric() {
System.out.println("风扇通电后开始工作");
work();
}
}
结果输出:
电视通电后开始工作
播放节目
冰箱通电后开始工作
冻东西
风扇通电后开始工作
吹。。。。。
实现多个接口
一个类只能继承一个父类,但能同时实现多个接口。
再来做一个练习:
案例:
某人是软件工程师,又是音乐家。如何在Java程序中实现?
定义人类作为抽象父类,包含人的基本属性和行为
定义编程接口,拥有编程能力
定义作曲接口,拥有作曲能力等
定义一个子类,继承人类,同时实现编程接口和作曲接口。
代码:
public class 多个接口 {
public static void main(String[] args) {
Musician m = new User();
m.compose();
}
}
abstract class People{
public abstract void eat();
public abstract void sleep();
}
interface Programmer{
void programming();
}
interface Musician{ // 音乐家
void compose(); // 作曲
}
class User extends People implements Programmer,Musician{
@Override
public void compose() {
System.out.println("作曲....");
}
@Override
public void programming() {
System.out.println("编程....");
}
@Override
public void eat() {
System.out.println("吃饭....");
}
@Override
public void sleep() {
System.out.println("睡觉....");
}
}
输出结果:
作曲....
这里是一个多态和接口的结合使用。
接口继承接口
interface A{
void method();
}
interface B extends A,C{
}
interface C{
void method();
}
设计提示
1.能用接口的地方,不用类。(面向接口编程)
2.一个模块尽量少知道其它模块的信息,知道的越少,对今后的维护越有利。