第八天(上) 接口
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第八天(上) 接口相关的知识,希望对你有一定的参考价值。
接口(interface):
接口不是类,而是对类的一组需求描述,这些类要遵循接口描述的统一格式进行定义
接口是功能的集合,只描述应该具备的方法,而没有具体的实现,具体的实现有接口的实现类(相当于接口的子类)类完成,这样将功能和实现分离,优化程序设计
接口无法被实例化,但可以用来声明一个变量.
接口的定义:
定义接口使用关键字interface
定义的接口文件仍为.java文件,虽然声明时使用的是interface关键字,但编译后任然会产生.claa文件,(我们可以把接口看成只包含功能声明的特殊”类”一个比抽象类更抽象的”类”)
定义格式
public interface 接口名{ 抽象方法1 ... }
注意事项:
接口可以无访问修饰符(默认),这时可以在同一个包内实现,不同的包下不可以,但是不可以用(protected修饰)
接口中的成员变量:
接口中可以定义变量,但变量必须是固定用public static final所修饰所以接口的成员变量为常量,并且一定要赋值
就算你不写系统也默认为 是public static final修饰,你写了其中的一个也还是这样
建议自己手写的时候写全
接口中的成员方法:
接口中可以定义方法,方法也有固定的修饰符public abstract 只能是这个
就算你不写系统也默认为 是public abstract修饰,你写了其中的一个也还是这样
建议自己手写的时候写全
实现类必须实现接口所有的抽象方法,实现类才能实例化,否则现实类为抽象类
在jdk1.8中允许我们给接口添加两种非抽象的方法实现
默认方法 添加default修饰 只能通过实现类名,后实现类的对象调用
Interface Demo{ Default String get(String a){ System.out.println(“1.8默认实现方法”); Return “”; } } 静态方法 static修饰 只能通过接口名调用 Static void Demo{ Systeo.out.println(“1.8静态方法”); }
接口的实现
注意
重写接口中的方法时,不能抛出强制性异常,只能在接口中,或者继承接口的抽象类中抛出强制性异常而java中除了RuntimeException外,都是强制性异常。
强制性异常:所谓强制性异常就是在编写程序的过程中必需在抛出异常的部分try catch 或者向上throws异常。
interface Fu2{ void show2(); } class Zi implements Fu1,Fu2 { // 多实现。同时实现多个接口。 public void show1(){} public void show2(){} }
类可以在继承的时候实现接口
格式:Zi extends Fu implements a{};extends和implements的书写顺序不能变
当一个类继承一个类,并且实现一个或者多个接口的时候,其中,父类和父接口中存在相同的方法a时,
如果子类有a方法的实现或者覆盖,就用子类的方法,编译工具提示是重写了父类的方法.
如果子类没有重写或者实现,就会将父类的方法作为接口抽象方法是实现.
类和接口的多实现:
接口最重要的体现:解决了多继承的弊端,将多继承这种机制在java中实现了
弊端:
多继承时,多个父类有相同的功能时,子类会产生不确定性,核心原因多继承的父类都有方法的主体,导致运行时,不能确定运行那个容内主体
怎么解决的?
接口中的方法没有方法体,实现接口时,实现类可以根据自己的需求写自己的方法体
类可以在继承的同时实现多个接口
子类通过继承父类扩展功能,通过继承扩展的功能都是子类应该具备的基础功能。如果子类想要继续扩展其他类中的功能呢?这时通过实现接口来完成。
接口的出现避免了单继承的局限性。父类中定义的事物的基本功能。接口中定义的事物的扩展功能。
代码演示
class Fu { public void show(){} } interface Inter { pulbic abstract void show1(); } class Zi extends Fu implements Inter { public void show1() { } }
实现多个接口时Default的问题
Jdk1.8中,如果多个接口有着相同的default方法,即方法名和参数列表相同。那么此时就会出现问题,无法识别到底是调用的哪个接口的方法,这个时候就必须要在实现类里面显式重写default的方法,而关于default的方法的重写,我们在实现类中不需要继续出现default关键字也不能出现default关键字。
重写的default方法必须的访问权限必须是public,因为default方法除了没有显式的访问修饰符外,只能用public访问限定符来修饰,而我们知道在Java中,要重写一个方法,访问限定符一定要大于父类或者接口指定的访问限定符范围,而且方法声明处抛出的异常也要大于后者。所以访问权限必须是public。
优先级问题
如果一个类实现的接口的默认方法和继承父类而来的方法同名时,优先掉用父类的方法
实现多个接口时static的问题
实现类实现多个接口,如果两个接口存在同名,同参数的静态方法存在的静态方法并不会冲突,并且无法使用实现类名.静态方法访问,也不能通过super方法,因为jvm不知道调用的是哪一个所以其只能通过各自的接口名.方法名访问,
实现类也可以存在同名的方法.
接口的继承
接口之间也可以中extends来实现继承关系一个接口能继承另一个接口,和类之间的继承方式比较相似。接口的继承使用extends关键字,子接口继承父接口的方法。
接口的多继承
在java中类的多继承时不合法的,但接口运行多继承.
格式:
public interface A extends B, C{ }
接口的思想:
电脑上就有许多的插口,比如usb,可以插入各种各样的设备,手机,u盘,打印机等等,这些设备为什么能插入呢?
主要原因就是这些设备在生产了符合了这些插口的使用规则,否则就无法插入也就无法使用.
接口就相当于这个插口.
接口的好处:
1接口的出现扩展了功能
2接口就是暴露出来的规则
3接口的出现降低了耦合性能,即实现了设备与设备之间的解耦合
接口的出现方便后期的使用和维护 ,一方使用接口,而另一方在实现接口例如 电脑使用接口usb 外设实现接口 usb
/*
* 自定义的鼠标类
* 满足USB接口规范
* 实现USB接口,重写抽象方法
*/
public class Mouse implements USB{ public void open(){ System.out.println("开启鼠标"); } public void close(){ System.out.println("关闭鼠标"); } } /* * 自定义的鼠标类 * 满足USB接口规范 * 实现USB接口,重写抽象方法 */ public class Mouse implements USB{ public void open(){ System.out.println("开启鼠标"); } public void close(){ System.out.println("关闭鼠标"); } } /* * 定义笔记本类 * 功能: 开机,关机,使用USB设备 */ public class Computer { public void openComputer(){ System.out.println("笔记本开机"); } public void closeComputer(){ System.out.println("笔记本关机"); } //使用USB设备方法,哪个设备 //方法的参数,就是USB设备 public void useUSB(USB usb){// USB usb = new Mouse() usb.open(); usb.close(); } }
接口和抽象类的区别:
犬:
行为:
吼叫;
吃饭;
缉毒犬:
行为:
吼叫;
吃饭;
缉毒;
由于犬分为很多种类,他们吼叫和吃饭的方式不一样,在描述的时候不能具体化,也就是吼叫和吃饭的行为不能明确。
当描述行为时,行为的具体动作不能明确,这时,可以将这个行为写为抽象行为,那么这个类也就是抽象类。
可是当缉毒犬有其他额外功能时,而这个功能并不在这个事物的体系中。这时可以让缉毒犬具备犬科自身特点的同时也有其他额外功能,可以将这个额外功能定义接口中。
接口和抽象类的总结
相同点:
都位于继承的顶端,用于被其他类实现或继承;
都不能直接实例化对象;
都包含抽象方法,其子类都必须覆写这些抽象方法;
区别:
抽象类为部分方法提供实现,避免子类重复实现这些方法,提高代码重用性;接口只能包含抽象方法;
一个类只能继承一个直接父类(可能是抽象类),却可以实现多个接口;(接口弥补了Java的单继承)
抽象类是这个事物中应该具备的你内容, 继承体系是一种 is..a关系
接口是这个事物中的额外内容,继承体系是一种 like..a关系
二者的选用:
优先选用接口,尽量少用抽象类;
需要定义子类的行为,又要为子类提供共×××时才选用抽象类;
以上是关于第八天(上) 接口的主要内容,如果未能解决你的问题,请参考以下文章