接口的概念
接口就是公共的行为规范标准,大家在实现时,只要符合规范标准,就可以通用。在Java中,接口可以看成是:多个类的公共规范,是一种引用数据类型。接口的定义格式与定义类的格式基本相同,将class关键字换成 interface 关键字,就定义了一个接口。
public interface 接口名称{ // 抽象方法 public abstract void method1(); // public abstract 是固定搭配,可以不写 public void method2(); abstract void method3(); void method4(); // 注意:在接口中上述写法都是抽象方法,更推荐方式4,代码更简洁 }
建议:
1.创建接口时,接口的命名一般以大写字母 I 开头。
2.接口的命名一般使用 “形容词” 词性的单词。
3.阿里编码规范中约定,接口中的方法和属性不要加任何修饰符号,保持代码的简洁性。
接口的使用
接口不能直接使用,必须要有一个"实现类"来"实现"该接口,实现接口中的所有抽象方法。
public class 类名 implements 接口名{ // ... }
注意:子类和父类之间是extends 继承关系,类与接口之间是implements 实现关系。
示例:
请实现笔记本电脑使用USB鼠标、USB键盘的例子
1.USB接口:包含打开设备、关闭设备功能
2.笔记本类:包含开机功能、关机功能、使用USB设备功能
3.鼠标类:实现USB接口,并具备点击功能
4.键盘类:实现USB接口,并具备输入功能
创建USB接口
public interface USB { void openDevice(); void closeDevice(); }
创建鼠标类Mouse,实现USB接口
public class Mouse implements USB { @Override public void openDevice() { System.out.println("打开鼠标"); } @Override public void closeDevice() { System.out.println("关闭鼠标"); } public void click(){ System.out.println("鼠标点击"); } }
创建键盘类KeyBoard,实现USB接口
public class KeyBoard implements USB { @Override public void openDevice() { System.out.println("打开键盘"); } @Override public void closeDevice() { System.out.println("关闭键盘"); } public void inPut(){ System.out.println("键盘输入"); } }
创建笔记本类Computer,使用USB设备
public class Computer { public void powerOn(){ System.out.println("打开笔记本电脑"); } public void powerOff(){ System.out.println("关闭笔记本电脑"); } public void useDevice(USB usb){ usb.openDevice(); if(usb instanceof Mouse){ Mouse mouse = (Mouse)usb; mouse.click(); }else if(usb instanceof KeyBoard){ KeyBoard keyBoard = (KeyBoard)usb; keyBoard.inPut(); } usb.closeDevice(); } }
创建测试类TestUSB
public class TestUSB { public static void main(String[] args) { Computer computer = new Computer(); computer.powerOn(); // 使用鼠标设备 computer.useDevice(new Mouse()); // 使用键盘设备 computer.useDevice(new KeyBoard()); computer.powerOff(); } }
接口的特性
接口类型是一种引用类型,但是不能直接new接口的对象。
public class TestUSB { public static void main(String[] args) { USB usb = new USB();//error USB是抽象的 无法实例化 } }
接口中每一个方法都是public的抽象方法,即接口中的方法会被隐式的指定为 public abstract(只能是public abstract,其他修饰符都会报错)
public interface USB { private void openDevice();// error 此处不允许使用private void closeDevice(); }
接口中的方法是不能在接口中实现的,只能由实现接口的类来实现。
public interface USB { void openDevice(); // 编译失败:因为接口中的方式默认为抽象方法 // error 接口抽象方法不能带有主体 void closeDevice(){ System.out.println("关闭USB设备"); } }
重写接口中方法时,不能使用默认的访问权限。
public interface USB { void openDevice(); // 默认是public的 void closeDevice(); // 默认是public的 } public class Mouse implements USB { @Override void openDevice() { //error System.out.println("打开鼠标"); } }
接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量。
public interface USB { double brand = 3.0; // 默认被:final public static修饰 void openDevice(); void closeDevice(); } public class TestUSB { public static void main(String[] args) { // 可以直接通过接口名访问,说明是静态的 System.out.println(USB.brand); // 编译报错:error 无法为最终变量brand分配值 USB.brand = 2.0; // 说明brand具有final属性 } }
接口中不能有代码块和构造方法
public interface USB { public USB(){} // 编译失败 {} // 编译失败 static {} // 编译失败 void openDevice(); void closeDevice(); }
接口虽然不是类,但是接口编译完成后字节码文件的后缀格式也是 .class。如果类没有实现接口中的所有的抽象方法,则类必须设置为抽象类。 jdk8中,接口中还可以包含default方法。
public interface ITest { //一定要被重写 void testA(); //static修饰不能被重写 static void testStatic() { System.out.println("testStatic()"); } //default修饰可以被重写也可以不被重写 default void defaultMethod() { System.out.println("defaultMethod()"); } } class TestDemo implements ITest { @Override public void testA() { System.out.println("重写testA()!"); } }
实现多个接口
Java中不支持多继承,但是一个类可以实现多个接口。
定义一个Animal的类
public class Animal { String name; public Animal(String name) { this.name = name; } }
提供两个接口 Run 和 Fly
public interface Run { void running(); } public interface Fly { void flying(); }
创建一个Bird
public class Bird extends Animal implements Run,Fly { public Bird(String name) { super(name); } @Override public void flying() { System.out.println(name + "在飞翔"); } @Override public void running() { System.out.println(name + "在跑"); } }
创建一个Dog
public class Dog extends Animal implements Run { public Dog(String name) { super(name); } @Override public void running() { System.out.println(name + "在飞快地跑"); } }
最后创建一个测试类TestInterface
public class TestInterface { public static void main(String[] args) { Dog dog = new Dog("大黑"); Bird bird = new Bird("小白"); dog.running(); bird.running(); bird.flying(); } }
注意:一个类实现多个接口时,每个接口中的抽象方法都要实现,否则类必须设置为抽象类。
接口间的继承
在Java中,类和类之间是单继承的,一个类可以实现多个接口,接口与接口之间可以多继承。即:用接口可以达到多继承的目的。接口可以继承一个接口, 达到复用的效果. 使用 extends 关键字。
interface IRunning { void run(); } interface ISwimming { void swim(); } // 两栖动物, 既能跑, 也能游 interface IAmphibious extends IRunning, ISwimming { }
接口间的继承相当于把多个接口合并在一起。
抽象类和接口的区别
核心区别:抽象类中可以包含普通方法和普通字段,这样的普通方法和字段可以被子类直接使用(不必重写),而接口中不能包含普通方法,子类必须重写所有的抽象方法。
区别 | 抽象类(abstract) | 接口(interface) |
结构组成 | 普通类+抽象方法 | 抽象方法+全局常量 |
权限 | 各种权限 | public |
子类使用 | 使用extends关键字继承抽象类 | 使用implements关键字实现接口 |
子类限制 | 一个子类只能继承一个抽象类 | 一个子类可以实现多个接口 |
关系 | 一个抽象类可以实现若干接口 | 接口不能继承抽象类,但是接口可以使用extends关键字继承多个接口 |