课时87:接口定义加强
摘要:接口最早的主要的一个特点是全部由抽象方法和全局常量组成,但是如果项目设计不当,就有可能出现非常严重的问题。
1.接口设计不当
2.观察普通方法定义
3.在接口中定义Static方法
01. 接口的不当设计
1.1早起接口设计原则
如上图所示,写了一个 IMessage 接口,如果只有一个子类的时候,当 IMessage 接口扩充的情况下,只需要在一个子类上去复写新方法即可;如果经过常年累月的发展,该接口的第1080个子类,这个时候突然发现接口的某个方法不足的时候,再次为接口追加新方法,并且这些方法实现相同,最早的设计就不合理了。
如果有1080个子类就意味着要把这方法在所有的子类上复写1080遍,最重要的是这方法的实现还一模一样。此时此刻对于任何一个开发者而言,重复拷贝1080遍,此操作都是一个不合理的操作,这就是一个不当设计,因此我们要避免这种问题的出现。
该操作是属于结构设计不当的结果,但是最初的时候任何人都不敢保证接口设计足够完善,在此情况下,为了方便子类的修改,我们往往不会让子类直接继承子类实现的接口,而是中间追加一个过度抽象类。
1.2 为什么要设计抽象类
为什么要加抽象类呢,其中有一个最重要的特点就是该类不能被直接实例化,在中间增加一个过度抽象类之后,假如发生了之前的问题,可以按照接下来的方式进行解决:如果要追加新方法,直接在抽象类中做出实现,最初实现之后,抽象类的所有子类不需要把所有的方法重复实现。
所以在最初写代码的时候,往往会通过这样的一个方案来解决关于接口功能扩充的一个操作方式,但是这种方案在JDK1.8之后改变了,从 JDK1.8 之后为了解决接口设计的缺陷,在接口之中允许开发者定义普通方法。
02.观察普通方法定义
普通方法是有严格要求的,举例来讲:首先定义一个 IMessage 接口,直接定义一个 Message 抽象方法,接下来定义一个 MessageImpl 类实现 IMessage 接口,再定义一个Message方法,该方法随便返回一个内容,比如“www.mldn.cn”这个网址。
现在直接执行JavaDemo,正常完成,如果按照传统方法来,突然增加一个方法,这方法对于当前子类即为复写,如果子类很多,那么就非常可怕。
在JDK1.8之后为了解决这个问题,比如该方法是一个公共方法,为Boolean类型的Connect()方法,所有类都具备,可以在Boolean前面增加Default,返回True,同时在此处写一个代码输出代码,打印输出“建立消息的发送通道。”,接下来在JavaDemo中:
if(msg.connect()){ System.out.println(msg.message()) },
因为增加了Default方法,再次编译仍然成功,所以这个代码说明的是,接口定义中除了抽象方法还有普通方法。接口中的普通方法必须追加Default声明,该方法属于挽救功能,所有在开发设计中不作为首选,最好的方式是在中间加上一个过度抽象类,因此过度抽象类不能直接实例化,并且可以提供普通方法。
除了可以追加普通方法之外,接口中还可以定义 Static 方法,而Static方法可以通过接口直接调用。
03. 在接口中定义Static方法
我们把Default去掉,在Message类中增加代码
if(this.connect()){ return “www.mldn.cn” }, 在 IMessage 接口中增加 public static IMessage getInstance(){ return new MessageImpl();//获得子类对象 } Static的特点是在没有实例化之后即可直接调用,所以我们直接写 IMesage msg = IMessage .getInstance();
随后正常进行消息的连接和发送,然后编译,程序再一次执行,成功返回,这就是Static方法,一旦项目增加了Static支撑之后,他的项目功能就会大大提升,可以取代抽象类方法。
但是不应该将这两个组成最为接口的主要设计原则,所写的代码还是应该奉行:接口就是抽象方法。全局常量的出现并不高,见得最对的就是抽象方法,其他的都是挽救原则,而不是设计原则。