接口
引入
usb插槽就是现实的接口
设备都可以插在usb槽上而不用担心不匹配,原因是制作usb插槽的厂家和生产设备的厂家遵守了统一的规定。
基本介绍
接口就是给出一些没有实现的方法封装到一起,到某个类要使用的时候再根据情况把这些方法写出来。
语法:
interface 接口名 {
//属性
//方法
}
使用:
class 类名 implements 接口{
自己的属性;
自己的方法;
实现接口的抽象方法;
}
注意事项:
-
在jdk7.0以前接口的所有方法都没有方法体,jdk8以后接口类可以有静态方法和默认方法。
-
接口中的抽象方法默认为
public abstract
修饰的,因此可以省略关键字abstract
和public
,如果加大括号“实现”,则里面 只能写静态方法 或 用default
修饰该方法(默认方法)。
//AInterface.java
public interface AInterface {
//属性
public int n1 = 10;
//抽象方法,省略关键字abstract
public void hi();
//jdk8以后使用默认方法
default public void OK(){
System.out.println("OK");
}
//jdk8以后可以使用静态方法
public static void hello(){
System.out.println("hello");
}
}
//interface01.java
public class interface01 {
public static void main(String[] args) {
}
}
//必须实现接口中的所有抽象方法
class A implements AInterface{
@Override
public void hi() {
System.out.println("hi");
}
}
实现场景举例
项目开发,一个项目经理管理三个程序员,项目经理可以定义一些接口,然后由程序员具体实现。
注意事项
-
接口不能被实例化(不能被
new
出来,但是可以接收一个实现了该接口的类)interface IA{} class A implements IA{}//类A实现了IA main中: //new IA();//错误 IA ia = new A();//正确
-
接口中方法是public方法,且接口中的抽象方法可以不用abstract修饰
-
一个普通类实现接口必须将所有方法都实现
-
抽象类可以不用实现接口的方法(因为抽象类本身就要让子类来实现)
-
一个类可以
implements
(实现) 多个接口
interface IB{}
interface IC{}
class Pig implements IB, IC{}//如果接口中有方法则均需要实现
-
接口中的属性只能是
final
的,由于隐藏了public static
,所以属性本身为:public static final xxx = 初始化值;
(必须初始化)public
修饰 :表示不能用其他范围修饰符来修饰static
修饰:表示可以直接用类名访问属性final
修饰:表示不能修改
-
访问接口属性:
接口名.接口属性
-
接口不能继承其他类,但是可以继承多个别的接口
- 代码层面上:一个
interface
不能implements
其他的interface
而是extends
- 代码层面上:一个
-
接口的修饰符只能是
public
和默认
,这点和类的修饰符是一样的。
练习
判断下面的代码有无语法错误,并给出main函数语句的输出结果
interface A{
int a = 23;//等价于public static final int a = 23;
}
class B implements A{}//正确,A中没有抽象方法,因此B中不写代码也可以
main中:
B b = new B();//创建了B类的b,而B实现了A,故可以访问A中的属性
System.out.println(b.a);//A中的a属性为public,故可以访问,结果为23
System.out.println(A.a);//a属性为static,故可以用类名访问属性,结果为23
System.out.println(B.a);//B实现了A,故可以访问A中属性,结果为23
接口和继承的区别
- 接口是对继承的补充
- 继承主要解决代码的复用性和维护性的问题
- 接口主要解决设计的规范问题,让其他类去实现
- 接口比继承更灵活
- 继承满足is - a关系,接口满足like-a关系
- 接口在一定程度上实现代码解耦(接口规范性+动态绑定)
接口的多态表现
-
多态参数:(和继承类似)
定义了一个接口,但是不同的类实现了该接口。在创建接口时,一个接口的变量可以指向不同的实现了该接口的类。
public class InterfacePolyParameter {
public static void main(String[] args) {
IF if01 = new Monster();//接口if01可以指向Monster类
if01 = new Car();//也可以指向Car类
}
}
interface IF{}//接口
class Monster implements IF{}//Monster类实现了该接口
class Car implements IF{}//Car类也实现了该接口
- 多态数组
案例:给Usb
数组中存放Phone
和Camera
对象,Phone
类还有一个特有的call()
方法。遍历Usb
数组,调用方法。如果是Phone
对象,还要调用call()
方法.
//InterfacePolyArr
public class InterfacePolyArr {
public static void main(String[] args) {
//创建一个接口类型的多态数组
Usb[] usbs = new Usb[2];
usbs[0] = new Phone_();//创建一个Phone_类
usbs[1] = new Camera_();//创建一个Camera_类
//遍历数组
for (int i = 0; i < usbs.length; i++) {
usbs[i].work();//usbs中存放的是不同的类,因此用到动态绑定机制
//判断类型后确定是否调用call
if(usbs[i] instanceof Phone_) {
((Phone_) usbs[i]).call();//此处向下转型
}
}
}
}
interface Usb{
void work();
}
class Phone_ implements Usb{
public void call(){
System.out.println("手机打电话");
}
@Override
public void work() {
System.out.println("手机工作中");
}
}
class Camera_ implements Usb{
@Override
public void work() {
System.out.println("相机工作中");
}
}
- 多态传递
一个类未实现一个接口时,不能创建该接口,除非该类实现了这个接口的子接口。实现了子接口,也相当于把父接口实现了,因此称为“传递”。
//InterfacePolyPass.java
public class InterfacePolyPass {
public static void main(String[] args) {
IG ig = new Teacher();//可以,因为接口类型的变量可以指向实现了该接口的类的对象实例
//由于IG继承了IH接口,而Teacher类实现了IG接口,实际上相当于Teacher类也实现了IH接口
IH ih = new Teacher();//正确
}
}
interface IH{}
interface IG extends IH{}
class Teacher implements IG{}