JAVA零基础小白自学日志——第二十一天


今日提要:接口

1.什么是接口

**定义:**接口像一个100%纯度的抽象类;用以弥补Java单继承的弱点;使用interface关键字定义;

JDK1.8之前的接口:

  • 允许多继承;
  • 没有构造方法;
  • 常量默认使用public static final修饰;
  • 方法默认使用public abstract修饰;
  • 接口继承接口使用extends关键字,不使用implement

JDK1.8之后的变化:

  • 新添加默认方法和类方法分别用default和static关键字修饰;
  • 这两种方法是有方法体的;

2.为什么引入接口

[1].问题的提出

  • 打个比方可能更容易理解,我们创建一个家用入户安装的程序,首先我们会创建一个家用电器的基类(抽象类),然后我们分别定义了电视机、收音机、录像机、空调、投影仪、豆浆机,热水器(呀!这些东西好像暴露年龄了)等等子类来实例化抽象类里面的方法,可我们程序要实现的功能家用电器入户安装,那么这里就有问题了,电视机可能需要安装,可能不需要安装;收音机、录像机、豆浆机根本不需要安装;空调、热水器和投影仪需要更复杂的安装;
  • 针对程序要求,我们来看第一种方法,在家用电器的基类里面直接添加一个工具方法、一个零件方法和一个安装方法,让所有子类都继承,直观来看就会发现有些方法不是子类必须的,那么你怎么保证不会出现,买了个豆浆机,却让你准备一个冲击钻,并且让你在墙上打八个眼的情况发生呢?
  • 然后为了避免上面这种情况的发生,我们把工具方法、零件方法和安装方法抽象了,让子类继承,这样不需要安装的子类就可以空置这些方法,虽然这样可以避免买了个豆浆机,却让你准备一个冲击钻,并且让你在墙上打八个眼的情况发生,但是明显那些不需要安装的子类,也要对外宣称我有这些方法,只不过我不用,也就是我们把很多没用的方法也塞进所有的子类,很明显我们也不希望这样的事情发生;
  • 我们还可以把工具方法、零件方法和安装方法放到需要安装的电器的子类里面,这样的好处就是我们可以让需要安装的电器里面有相应的方法,而不需要安装的电器里面没有那些没用的方法,但是这样我们就必须让所有参与编程的人都知道这个要求,这样的不可靠性有多大,不用详细说了吧,最重要的一个问题就是不能使用基类作为多态类型;

[2].问题的解决

  • 所以我们真正需要的是一个类,一个包含工具方法、零件方法和安装方法的超类;
  • 保证所有需要安装的电器都可以继承超类的方法,而不用对每个程序员都讲一遍规则;
  • 这样所有需要安装的电器也都可以用基类的多态;
  • 但是我们同样面对了一个更大的问题,我们的一部分子类需要实例化两个超类,这就是一个明显的多重继承,如果两个超类里面有相同的方法,那么子类到底要运行那个方法呢,允许多重继承,就明显会出现死亡菱形的状态,而Java的单继承解决了多继承会导致死亡菱形的出现;
  • 这就让我们的问题回到了原点,我们如何解决这种需要两个超类的问题上了;
  • Java为了解决这种问题提供了一个解决方案,就是接口

3.接口到底是什么?它是如何解决多重继承的?

[1].接口到底是什么:

  • 接口是一个100%抽象类,虽然JDK1.8以后接口里面还允许存在有方法体的默认方法和静态方法,这个一会讨论,不过最初的接口就是被定义为一个100%的抽象类的
  • public interface XXX{....}定义了一个接口,public class BBB extends AAA implements XXX{.....}这句的意思就是一个名为BBB的子类继承了一个名为AAA的父类,并调用了一个名为XXX的接口;
  • 接口的实际意义更近似于一个工具集,继续用入户安装家用电器举例子,对于家用电器的基类,豆浆机是家用电器,热水器是家用电器,所以当创建豆浆机和热水器类的时候,public class 豆浆机 extends 家用电器{.....} public class 热水器 extends 家用电器{.....}这两个类完全属于BBB是一个AAA的这种明确的继承关系,不过这里有一个很明显的问题,豆浆机用户买回来,不需要进行安装就可以使用,而热水器却需要用冲击钻在墙体上打孔,并且放置膨胀螺栓,用扳手紧固,用户才可以使用,针对这个情况,我们先要去定义三个接口
  • 两个工具接口public interface 扳手{.....} public interface 冲击钻{.....}还有一个零件接口public interface 螺栓{.....},然后我们来看热水器的类最终会定义成什么样子public class 热水器 extends 家用电器 implements 扳手,冲击钻,螺栓 {.....},虽然热水器要实例化家用电器里面的方法,也要实例化扳手、冲击钻和螺栓里面的全部方法,但是这个意义完全不同,热水器和家用电器的关系是是一个的关系(is-a)继承关系,热水器会扩展家用电器类,而热水器和扳手、冲击钻、螺栓的关系是有一个的关系(has- a),它只是要应用它们的方法,而不会扩展它们,如果此时我们添加了一个和家用电器无关的类,比如自行车类,而自行车类也会用到扳手和螺栓public class 自行车 implements 扳手,螺栓 {.....}
  • 接口与继承的无关性,就体现在这里了, 接口就是一些特定的抽象方法集,那个超类的子类需要实例化某些方法了,就把含有这些抽象方法的接口添加给这个类;

[2].接口如何解决多重继承的

  • 接口解决多重继承的原理很简单,就是让所有的方法都抽象
  • 在之前的讨论里面我们探讨过解决多重继承的方法之一,就是把所有的方法都抽象到基类里面,这样,我们的第一个具体的子类就会实例化这些方法,当然其中的弊端就是,无论需要与否,我们的子类都要声明这些方法,而接口就避免了这种问题的出现,我们可以在需要的时候调用需要的接口,而不需要这些方法的子类就无需声明这些方法;
  • 而这些接口也可以应用于不同的继承树,可以明确的看出接口与继承树无关;
  • 那么这些被调用的接口并不影响原来的继承关系,原来的继承关系中的多态应用并没有受到影响;

[3].接口的继承

  • 首先明确,接口是可以继承的
  • 并且接口是允许多重继承的,比如,我们现在有个扳手接口,还有一个电动工具接口,而我们又创建了一个电动扳手的接口,电动扳手,本身属于扳手,也属于电动工具,定义这个情况的代码就是public interface 电动扳手 extends 扳手,电动工具{.......};
  • 这里就要有朋友问了,不是Java不允许多继承么?我们需要明白的是接口的多继承和咱们说的类的继承有一个原则性的区别,接口不会实例化父系的接口,和类是完全不同的,也正因为这个原因接口是允许多继承的;

明天我们再来继续讨论接口的静态方法和默认方法,还有接口和抽象类的区别,今天就到这里了

  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值