# Interface 接口

考虑一个场景, 在中国所有家用电器的充电器都遵循一个标准， 那就是充电电压为 220V 。为此，我们实现了一个接口 ICharger。&#x20;

* 接口有关键字 interface 表示，接口一般以大写字母 I 打头命名。
* 我们在这个接口里面设置了一个 maxVoltage 变量表示充电电压，chargerVoltage 用于输出充电电压到命令行。chargerVoltage() 函数设置为 static 表示这是这个标准的固有属性，充电电压就是220V，不能改变。
* chargerType()表示输出充电器种类的函数, 比如是两孔还是三孔？这个交给这个接口的类去实

```java
public interface ICharger {
    int maxVoltage=220;//220伏 充电电压

    static void chargerVoltage() {
        System.out.println("默认充电电压 : "+maxVoltage +" V");
    }

    //非static和default函数,一定要重写
    void chargerType() ;
}
```

接口中的所有成员变量和函数 访问限制符 都默认是 public, 可以不写。这也非常好理解, 因为标准就是给别人用的，就是应该公开透明，让大家去遵守。

接口中的所有成员变量 都是 final static 型。这样非常好理解, 因为标准是不能改的，标准是不随实现这个标准的对象变化而变化的。比如 maxVoltage 表示充电电压，就应该是220V， 不能更改。要是更改了，这个标准也就变了。

考虑另一个标准：上网。但是， 具体怎么上网，是用WIFI 还是用 SIM卡上网不知道。我们可以让上网这个接口被其他接口去继承。

```java
public interface INet {
    void connect();
}
```

WIFI接口，继承了 上网接口。同时将connect 设置为 default 函数。设置为default函数的意义在于，给这个函数一个默认的函数体，如果实现这个接口的类不重写default函数，也可以调用default函数。

```java
public interface IWIFI extends INet{
    default void connect() {
        System.out.println("使用WIFI上网");
    }
}
```

类似的，还有一个 SIM卡接口， 继承了上网接口。我们也将connect 设置为 default 函数。

```java
public interface ISIM extends INet{
    default void connect() {
        System.out.println("我使用SIM卡上网");
    }
}
```

现在有一个智能手机 SmartPhone类，实现了 ICharger 接口，IWIFI 接口，ISIM接口。并且对 chargerType 和 connect 函数进行了重写。

```java
public class SmartPhone implements ICharger,IWIFI,ISIM {
    @Override
    public void chargerType() {
        System.out.print("智能手机使用两孔充电器,");
        ICharger.chargerVoltage();
    }

    @Override
    public void connect() {
        System.out.println("智能手机使用 WIFI 和 SIM卡 上网");
    }

}
```

测试一下我们写的 SmartPhone 类

```java
public class SmartPhoneTest {
    public static void main(String[] args) {
        SmartPhone phone = new SmartPhone();
        phone.connect();//输出: 智能手机使用 WIFI 和 SIM卡 上网
        phone.chargerType();//输出: 智能手机使用两孔充电器,默认充电电压 : 220 V
    }
}
```

## 总结一下 Java 接口

* 接口表示一个标准，所有实现了这个标准的类都遵循一定的规则。
* 接口可以被继承。
* 一个类可以实现多个接口。
* 接口默认是abstract的，接口是不能被实例化的, 只能被实现。
* 接口的成员变量默认是 final, static 类型的，因为标准是不能更改的，成员变量代表了标准的固有属性。
* 接口函数可以是static类型，表示这个函数代表了这个接口的固有属性。
* 接口函数还可以是default类型，表示给这个函数一个默认的函数体。
* 如果接口函数不是static，也不是default类型，接口函数必须要被实现接口的类重写。
