【第二十章】接口的定义与使用
一.接口基本定义:
当你可以灵活的使用抽象类和接口进行设计的时候,那么基本上就表示你面向对象的概念理解了,需要大量的代码积累。
抽象类与普通类相比最大的优势在于:可以实现对子类覆写方法的控制。但是在抽象类中可能依然保留有一些普通方法,而普通方法里可能会涉及到一些安全或者隐私的问题,那么这样在我们进行开发的过程之中,如果要想对于外部隐藏所有的实现细节,则可以通过接口来进行描述。
接口可以理解为一个纯粹的抽象类(最原始的定义:接口之中只包含抽象方法和全局常量),但是从JDK1.8开始由于引入了Lambda表达式的概念,所以接口的定义也得到了加强,除了抽象方法和全局常量之外,我们还可以定义普通方法或静态方法。如果从设计本身来讲,接口之中的组成还是应该以抽象方法和全局常量为主。
在Java中接口主要使用interface关键字来定义:
范例:定义一个接口:
//由于类名称和接口名称的要求相同,所以为了区分类和接口,往往在接口名称前加上I(interface)
interface IMessage{ public static final String Info = "梓同科技有限公司"; public abstract String getInfo(); //抽象方法 }
但是现在很明显的问题出现了,此时的借口肯定无法直接产生实例化对象,所以对于接口的使用原则如下:
1.接口需要被子类实现(implements),一个子类可以实现多个父接口。
2.子类如果不是抽象类,则必须覆写接口中的所有抽象方法。
3.接口对象可以利用子类对象的向上转型进行实例化。
范例:定义接口子类:
interface IMessage{ public static final String Info = "梓同科技有限公司"; public abstract String getInfo(); //抽象方法 } class MessageImp implements IMessage{ //子类实现接口 public String getInfo(){ return "有内鬼,终止交易"; } } public class SSS { public static void main(String [] args){ IMessage mgr = new MessageImp(); System.out.println(mgr.getInfo()); System.out.println(IMessage.Info); } }
以上是一个接口的基本使用,但是在Java里面之所以使用接口主要的目的是一个子类可以实现多个接口。
利用接口可以实现多继承的概念。
范例:子类实现多个父接口:
interface IMessage{ public static final String Info = "梓同科技有限公司"; public abstract String getInfo(); //抽象方法 } interface IChannel{ public abstract boolean Connect(); } class MessageImp implements IMessage,IChannel{ public boolean Connect(){ System.out.println("通话建立"); return true; } public String getInfo(){ if(this.Connect()){ return"加密处理信息发送成功"; } return "有内鬼,终止交易"; } } public class SSS { public static void main(String [] args){ IMessage mgr = new MessageImp(); System.out.println(mgr.getInfo()); } }
但是这个时候就需要考虑一个实际的情况了,关于对象的转型问题。
此时MessageImpl子类的对象可以任意的实现父接口的转换。
范例:观察转换:
public class SSS { public static void main(String [] args){ IMessage msg = new MessageImp(); IChannel mgr = (IChannel)msg; System.out.println(mgr.Connect()); } }
接口是不允许去继承父类的,所以接口绝对不会是Object的子类,但是根据之前的分析可以发现,MessageImp是Object的子类,所以接口一定可以接受Object接收。
范例:观察Object类和接口转换
public class SSS { public static void main(String [] args){ IMessage msg = new MessageImp(); Object mgr = msg; IChannel chan = (IChannel)mgr; System.out.println(chan.Connect()); } }
Object类对象可以接受所有数据类型,包括基本数据类型、类对象数据类型、接口对象、数组。
由于接口是一个公共的定义标准,所有接口中所有的抽象方法都为public类型,也就是说写与不写都是一样的,下面俩个代码完全一样:
完整定义 | 简化定义 |
interface IMessage{ public static final String Info = "梓同科技有限公司"; public abstract String getInfo(); //抽象方法 }
|
interface IMessage{ String Info = "梓同科技有限公司"; String getInfo(); //抽象方法 }
|
到这里我们已经实现了接口的定义,但是在实际开发中,接口的子类实现有可能是抽象类,一个抽象类可以实现多个父接口,而一个普通类只能继承一个抽象类并且实现多个父接口,但是要求先继承后实现。
interface IMessage{ public static final String Info = "梓同科技有限公司"; public abstract String getInfo(); //抽象方法 } interface IChannel{ public abstract boolean Connect(); } abstract class DatebaseConnection{ public abstract boolean getConnection(); } class MessageImp extends DatebaseConnection implements IMessage,IChannel{ public boolean Connect(){ System.out.println("通话建立"); return true; } public String getInfo(){ if(this.Connect()){ if(this.getConnection()){ return"加密处理信息发送成功"; } return"加密处理信息发送失败"; } return "有内鬼,终止交易"; } public boolean getConnection(){ return true; } } public class SSS { public static void main(String [] args){ IMessage msg = new MessageImp(); Object mgr = msg; IChannel chan = (IChannel)mgr; System.out.println(chan.Connect()); } }
虽然接口无法继承一个父类,但是接口却可以通过extends继承多个父接口,此时成为接口的多继承、
范例:实现接口多继承:
interface IMessage{ public abstract String getInfo(); //抽象方法 } interface IChannel{ public abstract boolean Connect(); } interface IService extends IMessage,IChannel{ public String service(); } class MessageService implements IMessage,IChannel,IService{ public String getInfo(){ return "获取数据库信息中,请稍后.."; }; public boolean Connect(){ return true; }; public String service(){ return "获取消息服务"; }; }
在实际开发中,接口的使用往往有三种形式:
1.进行标准设置;
2.表示一种操作的能力;
3.暴露远程方法视图,这个一般都在RPC分布式开发中使用。