转载

Java学习笔记之二——继承与接口

零、前言

《HeadFirstJava》是最通俗易懂也是最适合小白入门的JAVA书。

很久很久以前,我在学习《HeadFirstJAVA》时,尝试着把自己理解的内容写成文章,于是就有了 《一个小白眼中的“面向对象”》 ,现在,书已经彻底读完了,所以要再写一些自己的体会。

在软件开发中,有这样一个规律:

  • 绝对不重复造轮子,只要一段代码出现了两次,就一定要把它们共有的代码抽象出来。

我们可以从这个角度,来看一看对象、类、接口、继承之间的关系。

类和对象

我们已经知道,类是对象的模板,对象是类的克隆。

当我们需要创建一系列相同的对象时,就把它们 共有的部分 抽象出来,因此就有了类。

Java学习笔记之二——继承与接口

类和继承

(一)

开始之前,我们先想一想,所有的动物都有吃饭这个方法eat(),如果每种动物都单独写一个eat()方法,那就是许许多多相同的代码。

Java学习笔记之二——继承与接口

既然又出现了相同的代码,我们可不可以把它们抽象出来呢?可不可以写一个通用的类,包含了这些共同的方法,而所有具体的类都“克隆”这个通用的方法呢?

当然可以,于是就有了下图:

Java学习笔记之二——继承与接口

这就是继承,被继承的类称为 父类 ,执行继承的类叫做 子类 ,继承的作用在于, 子类拥有了父类的所有属性和方法

对于初学者来说听到这个词,可能会想到现实中的财产继承,但计算机的继承和这个并不一样,如果用一个更贴切的词语来形容计算机的“继承”,那应该是生物学中的“ 遗传 ”。

为什么说计算机的继承有点像“遗传”呢,因为并不是子类继承之后,父类就没有了,而是把父类完整的复制一份,无论发生多少次继承,父类都还是那个父类,一点也没有减少。

  • 所以, 子类可以获得父类的方法和属性

(二)

虽然所有的动物都会吃,但并不是所有动物都会飞,如果想给鸟类添加fly()的方法,可以吗?

当然可以。

Java学习笔记之二——继承与接口

  • 所以, 子类可以定义自己独有的方法

(三)

如果所有陆生动物都会走路,但并不是所有的动物走路姿势都一样,那么可不可以只给几种特殊的动物定义单独的wolk(),而其他的动物使用父类的work()呢?

当然可以。

Java学习笔记之二——继承与接口

  • 所以,子类可以覆盖父类的方法

因此又引出一个结论:

当对象被调用了一个方法,程序会先从 对象所属的类 中寻找此方法,如果没有,再去此类的 父类 中寻找,如果还没有,就一直 向上寻找 ,直到找到 最顶层的父类 ,如果还没有,就会报错。

(四)

我们继续第三个问题,所有的动物都有鸣叫的方法call(),但是所有的动物叫声都不一样,那么如果new一个Animal对象,它会怎么叫呢?

Java学习笔记之二——继承与接口

答案是:根本就不存在Animal这种对象,因此,有些类是 不能new 的。这种对象一旦new出来,不仅没有意义,而且很危险。

所以,必须要对这种特殊的类,做一个标注,使它不能new,但可以被继承。

这样,就有了 抽象类 ,抽象类中至少有一个 抽象方法

Java学习笔记之二——继承与接口

抽象的,就是不具体的,这意味着只需要关注抽象方法的功能,而 不关心它的具体实现方式 。抽象方法只有方法名、返回值类型,而 没有语句 ,所以它不能被执行。

抽象类只有被具体类继承,并且通过覆盖父类的方法,把抽象方法实现之后,才能被new出来。

Java学习笔记之二——继承与接口

因为上图中的Bird,覆盖了Animal的Call(),它不包括任何抽象方法,所以Bird是一个具体的类,可以被new出来。

类和接口

(五)

人类是哺乳类动物也是灵长类动物,那么可以同时继承两个类吗?

在回答问题之前,先来看一个例子:

播放器按照功能可以分为CD、VCD、DVD,他们都有播放方法Play()。

Java学习笔记之二——继承与接口

如果有一种新型的VCD和DVD的综合播放器,那应该怎么继承呢?

Java学习笔记之二——继承与接口

同时继承两个父类,看似这样没问题,但实际调用Play()的时候,到底调用哪个父类的Play()方法呢?

所以这是不行的,事实上,Java也是不允许这样做的。

那么如果有这种“继承”两个类的需求,怎么办呢?

有一种方法,就是把Play()变成抽象方法,让复合播放器实现这个抽象方法,即可。

Java学习笔记之二——继承与接口

但这样做,只是把多重继承变成了单一继承,虽然可用,但没有从根本上解决问题。

于是,接口出现了, 接口 的出现就可以解决多重继承的问题。

(六)

如果有一种宠物猫,它既有猫的属性,也有作为宠物的功能,按理说,它应该同时继承于Animal和Pet这两个类,可现实是不允许这么做。

Java学习笔记之二——继承与接口

如何用接口实现呢?——把Pet类的所有方法都变成抽象类!而Animal不变。

Java学习笔记之二——继承与接口

这样,从理论上可以避免方法的冲突。为什么呢?因为实现抽象方法必须要覆盖,这样,即使父类和这个抽象类有重名方法,也会被子类覆盖掉。

但Pet毕竟还是个类啊,Java不允许继承两个类。

所以,什么是接口呢?接口就是100%抽象的类。 接口只有抽象方法

现在的Cat类依然可以 继承 Animal,但对于Pet来说,就不是 继承 了,而是实现了Pet接口。

Java学习笔记之二——继承与接口

由于接口实100%抽象的,所以永远也不会出现方法重名了。

用一句话概况就是,一个类只能继承另一个类,接口只能继承另一个接口,但类可以实现多个接口。

其实接口(interface)也属于类(class),那么他们有什么区别呢?

类是用来New对象的,接口是用来被实现的,所以当某个类实现了某个接口之后,它就具备了这个接口的所有功能。因此才说:接口实际上是一种协议、一种规范。

总结

让我们回到这个规律:

  • 绝对不重复造轮子,只要一段代码出现了两次,就一定要把它们共有的代码抽象出来。

因为同样的对象出现了两次,所以把对象的共同点抽象出来,就有了类。

因为两个类有相同的功能,所以把相同的功能抽象出来,就有了继承。

因为要解决继承两个类的

原文  https://segmentfault.com/a/1190000022532828
正文到此结束
Loading...