接口是面向对象(下)中一块十分重要的部分,还包含前面抽象类的知识,务必扎实掌握。
接口:
概念:在java中,接口中可以看成是:多个类的公共规范,是一种引用数据类型。
语法:public interface 接口名 public class 类名 implements 接口名
public abstract void 方法名() public static final 变量名;
【1】:java8开始,允许接口定义了一个default方法,可以有具体的实现。
【2】:接口当中不能通过new关键字实例化。
【3】:接口也可以发生向上转型和动态绑定。
【4】:接口当中不能有构造方法和代码块。
【5】:当一个类实现接口中的方法后,类中的方法不能不加public。
【6】:java不支持多继承,但一个类可以实现多个接口,比如public Test implements A,B
【7】:一个类实现多个接口,每个接口中的抽象方法都要重写,否则类必须设置为抽象类。
【8】:接口可以继承另一个接口,使用extends关键字,达到复用的效果。
一、USB接口实例。
(1):定义了一个USB接口:
再定义了一个brand变量,默认是public static final 修饰,意味着brand不能被修改。之后再分别定义了两个抽象方法open和close,默认由public abstract修饰,且只能是public abstract。
(2):定义了一个Mouse类用来实现USB接口:
分别重写open、close方法,给出click方法,并分别打印“打开鼠标”、“关闭鼠标”、“鼠标点击”的语句。
接口中的方法是不能在接口中实现的,只能由实现接口的类来实现。
(3):定义了一个KeyBoard类来实现USB接口:
分别重写open、close方法,给出input方法,分别打印“打开键盘”、“关闭键盘”、“键盘输入”的语句。
接口中的方法是不能在接口中实现的,只能由实现接口的类来实现。
(4):定义了一个LapTop类:
分别给出了一个powerOn和powerOff方法,分别打印“打开笔记本电脑”和“关闭笔记本电脑”语句。
再给出了一个useUSB方法,返回值类型为void,参数类型为USB,参数名为device。先通过调用open方法打开设备,再通过if语句和instanceof语句判断device是Mouse类还是KeyBoard类,如果是Mouse类就调用click方法,如果是KeyBoard方法就调用input方法。 最后调用close方法就关闭设备。
第17行代码:将device类型强制转换为Mouse类型,并调用click方法,打印“鼠标点击”语句。
第20行代码:将device类型强制转换为KeyBoard类型,并调用input方法,打印“键盘输入”语句。
(5):最后的测试类Test3:
在main方法中,不能直接new(接口)对象,通过LapTop类实例化对象laptop,并调用powerOn方法,打开笔记本电脑。通过KeyBoard类实例化对象keyboard,并调用useUSB方法,传入参数keyboard。接着通过Mouse类实例化对象mouse,并调用useUSB方法,传入参数mouse。最后调用powerOff方法,关闭笔记本电脑。
抽象类与接口的区别:抽象类可以包含普通方法和普通字段,这样的普通方法和字段在子类中可以直接使用(不用重写),抽象类本身不能被实例化,要想使用,只能创建该抽象类的子类,然后在子类中重写抽象方法。
而接口中不能包含普通方法,子类必须重写所有的抽象方法,且接口中不能有构造方法,不能通过接口new实例化对象。
(6):输出结果:
二、java不支持多继承,但一个类可以实现多个接口;且一个类可以继承另一个类后再实现多个接口。
(1):定义了一个Animal父类,并定义了一个name变量,给出了一个有参构造方法,通过this关键字引用。
(2):定义了一个IFlying接口,并定义了一个fly的抽象方法,这里的方法默认是public abstract修饰,所以加不加public都可以。
(3):定义了一个ISwimming接口,并定义了一个swim方法,这里的方法默认是public abstract修饰,所以加不加public都可以。
(4):定义了一个IRunning接口,并定义了一个run方法,这里的方法默认是public abstract修饰,所以加不加public都可以。
(5):定义了一个Fish子类,继承父类Animal,并实现接口ISwimming,因为鱼只会游泳,不能跑和飞。给出一个有参构造方法,并重写接口中的swim方法,打印游泳的语句。
(实现接口的类一定要重写接口中所有的抽象方法,否则必须将类设置为抽象类,十分重要!!!)
(6):定义了一个Cat子类,继承父类Animal,并实现接口IRunning,因为猫只会跑,不会跑和游泳。给出了一个有参构造方法,并重写run方法,打印跑的语句。
(实现接口的类一定要重写接口中所有的抽象方法,否则必须将类设置为抽象类,十分重要!!!)
(6):定义了一个Frog子类,继承父类Animal,并实现接口IRunning和ISwimming,因为青蛙会跑和游泳,不能飞。给出了一个有参构造方法,并分别重写run和swim方法,打印跑和游泳的语句。
(实现接口的类一定要重写接口中所有的抽象方法,否则必须将类设置为抽象类,十分重要!!!)
(7):定义了一个Duck子类,继承父类Animal,实现接口ISwimming、IRunning和IFlying,因为鸭子会游泳、会跑、也会飞。给出一个有参构造方法,然后分别重写swim、run、fly方法,打印相对应的语句。
(实现接口的类一定要重写接口中所有的抽象方法,否则必须将类设置为抽象类,十分重要!!!)
(8):最后的测试类Test6,在main方法中,分别通过各自的类名实例化对象cat、fish、frog、duck,然后各自相应调用属于自己的方法并打印语句。不能直接通过接口实例化对象!
(9):输出结果:
(10)这样设计的好处是:时刻牢记多态的好处,让程序猿忘记类型。有了接口以后,类的使用者就不用再关心具体类型,而只关注某个类是否具备某种能力。
在以上代码中,我们可以不关注到底是哪种动物,只要参数会跑或者会游泳或者会飞就行,甚至不是动物都可以,只要满足三项中的一项就可以,大大降低了对类型的要求,减少了工作量。