基本定义:
如果在开发的过程中,如果想完全的对外面隐藏实现过程,则可以通过接口进行描述。
接口可以理解为一个纯粹的抽象类。JDK1.8引入了Lambda表达式的概念,除了抽象法法语全局常量之外,还可以定义普通方法活静态方法。但是从设计角度来讲,接口之中的组成还是应该以抽象方法和全局常量为主。
接口主要由interface定义接口。
特性:
1.接口需要被子类实现,一个子类可以实现多个接口。
2.子类(如果不是抽象类)一定要覆写接口之中的全部抽象方法。
3.接口对象可以利用子类对象的上转型进行实例化。
接口的基本使用:
interface IMessage{
public static final String INFO = "111";
public abstract String getInfo();
}
class MessageImpl implements IMessage{
public String getInfo(){
return "test";
}
}
class Untitled {
public static void main(String[] args) {
IMessage msg = new MessageImpl();
System.out.println(msg.getInfo());
System.out.println(msg.getClass());
System.out.println(IMessage.INFO);
}
}
以上是接口的基本使用,但是在java里面之所以使用接口的主要目的是一个子类可以实现多继承的概念。
实现多个接口:
interface IMessage{
public static final String INFO = "111";
public abstract String getInfo();
}
interface IChannel{
public abstract boolean connect();
}
class MessageImpl implements IMessage,IChannel{
public String getInfo(){
if (this.connect()) {
return "消息已经成功发送";
}
else {
return "通道获取失败,无法获取消息";
}
}
public boolean connect(){
return true;
}
}
class Untitled {
public static void main(String[] args) {
IMessage msg = new MessageImpl();
System.out.println(msg.getInfo());
System.out.println(msg.getClass());
System.out.println(IMessage.INFO);
}
}
多实现带来的隐患:
interface IMessage{
public static final String INFO = "111";
public abstract String getInfo();
}
interface IChannel{
public abstract boolean connect();
}
class MessageImpl implements IMessage,IChannel{
public String getInfo(){
if (this.connect()) {
return "消息已经成功发送";
}
else {
return "通道获取失败,无法获取消息";
}
}
public boolean connect(){
return true;
}
}
class Untitled {
public static void main(String[] args) {
IMessage msg = new MessageImpl();
IChannel chn = (IChannel)msg;//两个不相关的接口通过实现的类互相转换成功。
System.out.println(chn.connect());
}
}
由于MessageImpl子类实现了IMessage和Ichannel两个接口,所以两个接口互相转化。
在java中接口不允许继承父类,所以接口绝对不会是Object的子类,但是MessageImpl是Object的子类,所以接口一定可以通过Object接收。
class Untitled {
public static void main(String[] args) {
IMessage msg = new MessageImpl();
Object obj = msg;
IChannel chn = (IChannel)obj;
System.out.println(chn.connect());
}
}
Object对象可以接收所有数据类型,包括基本数据类型、类对象、接口对象、数组。
由于接口描述的是一个公共定义的标准,所以接口之中所有的抽象方法的访问权限都为public,所以写于不学都一样。
接口可以多继承:
interface IMessage{
public static final String INFO = "111";
public abstract String getInfo();
}
interface IChannel{
public abstract boolean connect();
}
interface server extends IMessage,IChannel{
public String service();
}
class MessageImpl implements server{
//实现接口需要实现全部的方法,包括被server继承的接口。
public String getInfo(){
if (this.connect()) {
return "消息已经成功发送";
}
else {
return "通道获取失败,无法获取消息";
}
}
public boolean connect(){
return true;
}
public String service(){
return "= =";
}
}
在实际的开发之中,接口的使用往往有三种形式:
1.进行标准设置
2.表示一种操作的能力
3.暴露远程方视图,这个一般在RPC分布式开发中使用。
接口定义加强:
接口不当设计:
接口追加方法,且继承的子类数量繁杂。此时在所有的子类中都需要增加方法的覆写。
解决方法:往往子类不是直接实现接口,而是在中间加一个抽象类。抽象类实现接口,子类继承抽象类。这种方案在JDK1.8之后,为了解决接口设计的缺陷,允许接口中定义普通方法。
interface IMessage{
public static final String INFO = "111";
public abstract String getInfo();
public default boolean connect(){//接口中的普通方法必须加default
return true;
}
public static Imessage getInstance(){
return new MessageImpl();
}
}
class MessageImpl implements IMessage{
public String getInfo(){
if (this.connect()) {
return "消息已经成功发送";
}
else {
return "通道获取失败,无法获取消息";
}
}
}
class Untitled {
public static void main(String[] args) {
IMessage msg = new MessageImpl();
System.out.println(msg.getInfo());
}
}
接口中加static方法:
interface IMessage{
public static final String INFO = "111";
public abstract String getInfo();
public default boolean connect(){
return true;
}
public static IMessage getInstance(){
return new MessageImpl();
}
}
class MessageImpl implements IMessage{
public String getInfo(){
if (this.connect()) {
return "消息已经成功发送";
}
else {
return "通道获取失败,无法获取消息";
}
}
}
class Untitled {
public static void main(String[] args) {
IMessage msg = IMessage.getInstance();
System.out.println(msg.getInfo());//消息已经成功发送
}
}
使用接口定义标准:
生活中有许多接口:例如USB、PCIE。电脑只承认USB接口,不关心USB后面的设备是U盘、键盘还是打印机。
指定标准样例:
interface IUSB{
public boolean check();
void work();
}
class Compute{
public void plugin(IUSB usb){
if (usb.check()) {
usb.work();
}
else {
System.out.println("error");
}
}
}
class KeyBoard implements IUSB{
public boolean check(){
return true;
}
public void work(){
System.out.println("working");
}
}
class Print implements IUSB{
public boolean check(){
return false;
}
public void work(){
System.out.println("working");
}
}
class Untitled {
public static void main(String[] args) {
Compute cmp = new Compute();
cmp.plugin(new Print());
cmp.plugin(new KeyBoard());
}
}
接口与抽象类的区别:
No | 区别 | 抽象类 | 接口 |
---|---|---|---|
1 | 定义关键字 | abstract class 名称{} | interfame 接口名称{} |
2 | 组成 | 构造、普通方法、静态方法、全局变量、普通方法 | 抽象方法 |
3 | 权限 | 各种权限 | 只能使用public |
4 | 子类使用 | extends关键字,单一继承 | implements关键字,可以多个继承 |
5 | 两者关系 | 抽象类可以实现若干接口 | 接口不允许继承抽象类,但是允许继承多个父接口。 |
6 | 使用 | 1、抽象类或接口必须定义子类 2、子类一定要覆写抽象类或接口的全部抽象方法 3、通过自雷的向上转型实现抽象类活接口对象实例化 |
当抽象类和接口都可以使用的情况下,优先考虑接口。