什么是接口?
在Java中,接口可以看成是多个类的公共规范,是一种引用数据类型。
使用关键字interface来定义接口
interface IRunning {
void run();
}
在创建接口时,接口的命名一般以大写字母I开头,接口的命名一般使用形容词词性的单词。【阿里编码规范中约定,接口中的方法和属性不要加任何修饰符号,保持代码的简洁性。】
public String name = "小王";
public static String name2 = "小王";
public static final String name3 = "小王";
name为斜体,因为一个变量如果被static修饰,则变量名就变成斜体了,而且静态常量必须赋初始值,否则会报错。
interface IRunning {
void run();
}
public class Test implements IRunning {
@Override
public void run() {
System.out.println("实现接口中的run方法");
}
}
interface IRunning {
void run();
public static void func() {
System.out.println("接口中static方法");
}
}
总结:接口中可以有3种方法,2种比较特殊(default修饰的方法,static修饰的方法)
接口不能直接使用,必须要有一个“实现类”,实现接口中的所有抽象方法
【注意:子类和父类之间是extends继承关系,类和接口之间是implements实现关系】
实现笔记本电脑使用USB鼠标、USB键盘的例子
①USB接口:包含打开设备、关闭设备功能
②鼠标类:实现USB接口,并具备点击功能
③键盘类:实现USB接口,并具备输入功能
④笔记本类:包含开机功能、关机功能,使用USB设备功能
package demo;
//Usb接口:包含打开设备、关闭设备功能
public interface IUSB {
void openDevice();
void closeDevice();
}
package demo;
public class KeyBoard implements IUSB{
@Override
public void openDevice() {
System.out.println("打开键盘");
}
@Override
public void closeDevice() {
System.out.println("关闭键盘");
}
public void inPut(){
System.out.println("键盘输入");
}
}
package demo;
public class Mouse implements IUSB{
@Override
public void openDevice() {
System.out.println("打开鼠标");
}
@Override
public void closeDevice() {
System.out.println("关闭鼠标");
}
public void click() {
System.out.println("鼠标点击");
}
}
package demo;
public class Computer {
public void open() {
System.out.println("打开电脑");
}
public void close() {
System.out.println("关闭电脑");
}
public void func(IUSB iusb) {
iusb.openDevice();
if (iusb instanceof KeyBoard) {
((KeyBoard) iusb).inPut();
}else if (iusb instanceof Mouse) {
((Mouse) iusb).click();
}
iusb.closeDevice();
}
}
package demo;
public class Test {
public static void main(String[] args) {
Computer computer = new Computer();
computer.func(new Mouse());
System.out.println("=========");
computer.func(new KeyBoard());
}
}
运行结果:
分析:在func方法中,发生了向上转型,传入的是接口类型,站在这个角度,我们就可以不关心usb这个引用到底引用了哪个对象,只要实现了这个接口的规范就可以传进来。
动态绑定和多态:从代码的角度,可以省略代码,而且还融入了设计的思想。
接口:会跑的、会游的、会飞的
package demo1;
public interface IRunning {
void run();
}
package demo1;
public interface ISwimming {
void swim();
}
package demo1;
public interface IFly {
void fly();
}
动物类:设计被抽象类
package demo1;
public abstract class Animal {
public String name;
public Animal(String name) {
this.name = name;
}
}
狗类:狗是一个动物,具备running这样的一个功能
package demo1;
public class Dog extends Animal implements IRunning{
@Override
public void run() {
System.out.println(name + "用四条狗腿在跑");
}
public Dog(String name){
super(name);
}
}
鱼类:鱼是一个动物,具备swimming这样的一个功能
package demo1;
public class Fish extends Animal implements ISwimming{
@Override
public void swim() {
System.out.println(name + "在水里游游游");
}
public Fish(String name) {
super(name);
}
}
鸭类:鸭是一个动物,具备running、swimming以及flying3个功能【实现多个接口】
package demo1;
public class Duck extends Animal implements IRunning, ISwimming, IFly{
@Override
public void fly() {
System.out.println(name + "在天上飞飞飞");
}
@Override
public void run() {
System.out.println(name + "在地上跑跑跑");
}
@Override
public void swim() {
System.out.println(name + "在水里游游游");
}
public Duck(String name) {
super(name);
}
}
机器人类:机器人有running这样的功能,但是机器人不是动物类。【因为接口让程序员忘记类型】
package demo1;
public class Robat implements IRunning{
private String name;
@Override
public void run() {
System.out.println(name + "用机器腿在跑");
}
public Robat(String name) {
this.name = name;
}
}
测试类:
package demo1;
public class Test {
public static void walk1(IRunning iRunning) {
iRunning.run();
}
public static void walk2(ISwimming iSwimming) {
iSwimming.swim();
}
public static void walk3(IFly iFly) {
iFly.fly();
}
public static void main(String[] args) {
Dog dog = new Dog("旺财");
walk1(dog);
System.out.println("===========");
Fish fish = new Fish("小鱼儿");
walk2(fish);
System.out.println("===========");
Duck duck = new Duck("唐老鸭");
walk1(duck);
walk2(duck);
walk3(duck);
System.out.println("===========");
Robat robat = new Robat("小王");
walk1(robat);
}
}
运行结果:
分析:在walk方法内部,我们并不关注到底是哪种动物,只要参数是会跑的就行,甚至参数可以不是“动物”,比如机器人,只要会跑,总而言之接口让我们忘记了类型,只要实现了这个接口就可以传。
package demo1;
public interface IRunAndSwim extends IRunning, ISwimming{
}
此时如果类要实现 IRunAndSwim 接口,则不仅要实现run方法,也要是心啊swim方法。
接口间的继承相当于把多个接口合并在一起。