JavaInterface
- 接口的基本介绍
- 接口的注意事项及使用细节
- 接口实现与类的继承
- 接口的多态性
接口基本介绍
-
接口就是给出一些没有实现的方法,封装到一起,到某个类要使用的时候,再根据具体情况把这些方法写出来。
接口的定义:
interface 接口名{ //属性 //方法 }
类实现接口:
class ClassName implements Interface { //自己的属性 //自己的方法 //必须实现的接口的抽象方法 }
-
在jdk7前,接口里的所以方法都没有方法体,即都是抽象方法。
-
jdk8后接口可以有静态方法,默认方法,也就是说接口中可以有方法的具体实现。但默认方法需要使用default关键字修饰
-
在接口中,定义抽象方法时可以省略abstract关键字。如果一个类实现了接口,则需要把接口的所有抽象方法都实现。
代码演示
创建接口Interface01
package com.interface_; public interface Interface01 { //定义属性 public int n =1; //定义抽象方法 public void A(); //定义默认方法 default public void B(){ System.out.println("我是默认方法"); } //定义静态方法 public static void C(){ System.out.println("我是静态方法"); } }
创建实现类InterfaceImp01
package com.interface_; public class InterfaceImp01 implements Interface01{ @Override public void A() { System.out.println("实现抽象方法"); } @Override public void B() { Interface01.super.B(); } }
创建测试类InterfaceTest
package com.interface_; public class InterfaceTest { public static void main(String[] args) { InterfaceImp01 interfaceImp01 = new InterfaceImp01(); interfaceImp01.A(); interfaceImp01.B(); //调用静态方法 Interface01.C(); } }
输出结果:
-
对于初学者来说,接口的概念不难理解。难的是不知道什么时候使用接口,下面例举应用场景来理解接口的使用:
- 现在要制作战斗机,武装直升机。专家只需要把飞机需要的功能/规格定下来即可,然后让工程师来实现
- 现在有一个项目经理,管理三个程序员,功能开发一个软件,为了控制和管理软件,项目经理可以定义一些接口,然后由程序员来实现。
接口的注意事项与使用细节
-
接口不能被实例化
-
接口中所有的方法都是public,接口中的抽象方法可以不用abstract修饰
interface Interface{ void say(); //相当于 public abstract void say(); }
-
一个普通类实现接口,就必须将该接口的所有方法都实现(可以使用alt+enter来解决)
-
抽象类去实现接口时,可以不实现接口的抽象方法
-
一个类可以同时实现多个接口。
创建接口Interface01
interface Interface01{ say(); }
创建接口Interface02
interface Interface02{ hi(); }
实现类dog
class dog implements Interface01,Interface02{ @Override public void hi(){ } @Override public void say(){ } }
-
接口中的属性只能是final,而且是public static final修饰符。属性的访问形式为接口名.属性名
interface Interface01{ int n = 1; //实际上是 public static final int n = 1;//必须初始化值 }
证明:创建测试类InterfaceTest
package com.interface_; public class InterfaceTest { public static void main(String[] args) { //此处可以直接调用接口Interface01的属性,证明该属性为static Interface01.n; Interface01.n = 10;//系统会报错,证明该属性被final修饰 } }
-
接口不能继承其他的类,但是可以继承其他接口。
interface Interface03 extends Interface01,Interface02{ }
而且继承其他接口时不用实现其他接口的方法。
-
接口的修饰符与类一样,只能是public或者是默认
-
思考题:下面程序是否正确,正确的话输出什么?
//创建接口 public interface Interface02 { int a = 23; } //创建接口实现类 public class InterfaceImp02 implements Interface02{ } //创建测试类 public class InterfaceTest { public static void main(String[] args) { InterfaceImp02 imp02 = new InterfaceImp02(); System.out.println(imp02.a); //因为InterfaceImp02实现了接口Interface02 所以也可以成功输出 System.out.println(InterfaceImp02.a); //a为static属性,所以可以输出 System.out.println(Interface02.a); } }
代码正确,输出结果为
接口实现与类继承
-
当子类继承了父类,就会**自动的拥有父类的功能(方法)。**而如果子类需要拓展功能,可以通过实现接口的方式拓展
-
可以理解成实现接口就是对Java单继承机制的一种补充
下面举个例子理解接口实现与类继承
例:假如有一只小猴子悟空,他继承了父亲的爬树技能。当他看到鱼儿在游泳时,就跟鱼儿学习了游泳技能;当他看到鸟儿在飞翔时,就跟鸟儿学习了飞翔技能…
代码演示:
创建猴子父类 Monkey
package com.interface_; public class Monkey { private String name; public Monkey(String name) { this.name = name; } public void climbing(){ System.out.println(name + "在爬树"); } }
子类LittleMonkey
package com.interface_; public class LittleMonkey extends Monkey{ public LittleMonkey(String name) { super(name); } }
此时,LittleMonkey继承了Monkey,所以很自然的会爬树
因为悟空需要拓展技能,我们创建接口FishAble和BirdAble
package com.interface_; public interface FishAble { public void Swimming(); }
package com.interface_; public interface BirdAble { public void flying(); }
而且LittleMonkey也实现了FishAble与BirdAble
package com.interface_; public class LittleMonkey extends Monkey implements BirdAble,FishAble{ public LittleMonkey(String name) { super(name); } @Override public void flying() { System.out.println(this.getName()+"通过学习,学会了飞翔"); } @Override public void Swimming() { System.out.println(this.getName()+"通过学习,学会了游泳"); } }
最终,悟空学会了飞翔与游泳
public class InterfaceTest { public static void main(String[] args) { LittleMonkey wuKong = new LittleMonkey("悟空"); wuKong.climbing(); wuKong.flying(); wuKong.Swimming(); } }
-
实现接口VS继承类
接口和继承解决的问题不同
- 继承的价值主要在于:解决代码的复用性和可维护性
- 接口的价值主要在于:设计好各种规范(方法),让它的实现类去实现这些方法。更加的灵活
接口比继承更加灵活
-
继承是满足is-a的关系,而接口只需满足like-a的关系即可。
比如:猫它是动物(is-a),而猫像鱼一样会游泳(like-a)
接口在一定程度上实现代码解耦(即:接口的规范性+动态绑定机制)
接口的多态性
-
接口类型的变量可以指向实现了接口类的对象实例
package com.interface_; public class InterfacePolyParameter { public static void main(String[] args) { //接口的多态体现 IF if01 = new Monster(); if01 = new Car(); } } interface IF{} class Monster implements IF{} class Car implements IF{}
-
多态参数的体现
演示一个案例:有一个接口UsbInterface usb,既可以接收手机对象,又可以接收相机对象,就体现了接口的多态(接口引用可以指向实现了接口的类的对象)
创建接口UsbInterface
package com.interface_; public interface UsbInterface { void start(); void stop(); }
创建接口实现类Phone1
package com.interface_; public class Phone1 implements UsbInterface{ @Override public void start() { System.out.println("Phone开始工作"); } @Override public void stop() { System.out.println("Phone停止工作"); } }
创建接口实现类Camera1
package com.interface_; public class Camera1 implements UsbInterface{ @Override public void start() { System.out.println("Camera开始工作"); } @Override public void stop() { System.out.println("Camera停止工作"); } }
创建类Computer01
package com.interface_; public class Computer01 { //1. UsbInterface usbInterface 说明Work的形参类型是UsbInterface //2. 这个参数可以接收实现了UsbInterface接口的类的对象实例 public void Work(UsbInterface usbInterface){ usbInterface.start(); usbInterface.stop(); } }
Tset
package com.interface_; public class InterfaceTest02 { public static void main(String[] args) { //创建手机对象,Phone1实现了UsbInterface接口 Phone1 phone1 = new Phone1(); //创建相机对象,Camera1实现了UsbInterface接口 Camera1 camera1= new Camera1(); //创建计算机对象 Computer01 computer01 = new Computer01(); //把手机接入电脑 computer01.Work(phone1); System.out.println("==============="); //把相机接入电脑 computer01.Work(camera1); } }
运行结果
-
多态数组的体现
演示一个案例:给定Usb数组中,存放Phone和Camera对象,Phone类还有一个特有的方法call(),请遍历Usb数组,如果是Phone对象,除了调用Usb接口定义的方法外,还需要调用Phone特有方法call。
创建接口Usb
interface Usb{ void Work(); }
创建接口实现类Phone2与Camrea2
class Phone2 implements Usb{ @Override public void Work() { System.out.println("Phone工作了"); } public void call(){ System.out.println("Phone打电话"); } }
class Camera2 implements Usb{ @Override public void Work() { System.out.println("Camera工作了"); } }
创建测试类InterfacePolyAry
package com.interface_; public class InterfacePolyAry { public static void main(String[] args) { //多态数组 ->接口类型数组 Usb[] usbs = new Usb[2]; usbs[0] = new Phone2(); usbs[1] = new Camera2(); for (int i = 0; i<usbs.length; i++){ usbs[i].Work();//多态绑定 //需要进行类型的向下转型 if(usbs[i] instanceof Phone2){ ((Phone2) usbs[i]).call(); } } } }
运行结果
-
接口存在多态传递现象(代码演示)
创建接口InterfacePoly1
interface InterfacePoly1{ void hi(); }
创建接口InterfacePoly2继承了接口创建接口InterfacePoly1
interface InterfacePoly2 extends InterfacePoly1{ }
创建接口实现类InterfacePolyImp
class InterfacePolyImp implements InterfacePoly2{ @Override public void hi() { System.out.println("hi"); } }
创建测试类InterfacePolyPass
package com.interface_; public class InterfacePolyPass { public static void main(String[] args) { //接口类型的变量可以指向实现了该接口的对象实例 InterfacePoly2 interfacePoly2 = new InterfacePolyImp(); //如果InterfacePoly2继承了InterfacePoly1接口,而InterfacePolyImp实现了InterfacePoly2接口 //那么实际上就相当于InterfacePolyImp实现了InterfacePoly1接口 //这就是所谓的接口多态传递现象 InterfacePoly1 interfacePoly1 = new InterfacePolyImp(); } }