天才第一步:Java零基础入门,就从这份阿里p7大佬分享的笔记学起

今日分享开始啦,请大家多多指教~

继承与多态既是类与类之间的关系,又是一种思考问题的方式。

继承

java里面有类这样的概念,你可以有Person类来指代人,也可以详细一点,用Teacher类来指代老师,也可以用childen类来指代孩子,那么这些类与类之间是否也有一定的关系呢?

答案是有的,比如作为一个老师,他既属于Teacher类,也属于Person类。又比如,狗既属于dog类,又属于animal类。那么我们发现针对于每一个对象来说,它都可以分属于很多种类别。

我们又可以想一想,科学界对于动植物的划分是可以从界门纲目科属种依次从大到小的来逐层划分的,因此,作为面向对象编程,我们也由此可以了解到一种如上述划分动植物一样的继承的思想。

话不多说,我们用代码来演示,请看如下代码

image.png

请看上图中,我写了animal类,cat类,bird类三个类,我们发现无论是animal,cat还是bird,它们都有属于自己的名字,都会吃东西,不同的是只有bird会飞。我们发现关于名字和吃的代码在三个类里面都是一样的,那么这是不是就造成了代码的冗余呢?

另外再思考一个问题,无论是什么动物,只要它是动物,它就一定会吃以及一定有名字,但不一定会游泳或者飞。因此我们是不是可以把animal设为一个父类,把cat和bird设为子类,将关于吃和名字的代码设置在animal里面,再让cat和bird继承animal,这样就能解决代码冗余的问题呢?

答案是可以的,具体请看如下代码

image.png

简化后的代码我们看到所有的有关名字和吃的代码我都放到animal里面,然后要记住一点是java里面使用extends来申明子父类的关系

比如 A extends B 那么,A就是B的子类,B就是A的父类,它们的关系是 is-a 的关系,比如Teacher extends Person,就代表了老师是一个(is a)人,又比如dog extends animal 就代表了狗是一个(is a)动物。这就是java里面的继承。

(注:父类,又称超类,基类。子类,又称派生类)

下面来说说继承的几点性质

1.我们发现其实继承关系里面,父类所含有的属性只是子类的一部分,子类对父类的功能进行了扩展和延伸。

2.java里面只支持单继承,也就是一个子类只能有一个父类。(C++/Python等语言里面支持多继承)

3.对于父类里面private的字段和方法,子类继承了,但是无法访问。

4.在子类的实例中也包含着父类的实例,通过使用super关键字来得到父类实例的引用。

多态

何为多态,就是多种状态嘛,结合我们的上文,我们可以知道如果一个男老师可以继承Teacher的属性又继承husband的属性,那么我们什么时候需要这个男老师来表现出老师的属性,以及什么时候需要来表现出丈夫的属性呢?

答案是如果这个男老师在学校里面,那么他就要表现出老师的属性,如果这个男老师工作结束回家了以后,他就要表现出丈夫的属性。这就是多态。首先要明确一点,多态是基于继承来实现的。

要想从代码上面来实现多态,我们就必须先了解向上转型、动态绑定

向上转型

向上转型,顾名思义,就是往上转嘛。具体操作就是将一个子类对象用一个父类引用去接收。

具体实例如下

image.png

如上图代码所示,这就是向上转型。向上转型可以发生在直接赋值(如上),方法传参,方法返回三种情况,下面再用代码来演示方法传参和方法返回两种情况。

image.png

image.png

动态绑定

动态绑定是向上转型的一个效果。如下图代码

image.png

我在子类B中写了一个返回类型,方法名称,传入参数与父类A中完全一致的eat方法,然后访问向上转型为类型A的变量b1的eat方法,按理来说,我将 b1 向上转型为 类型A ,那么我调 eat 方法应该也是调A中的 eat 方法,但其实最终程序运行的结果是调用了子类B的 eat 方法,这样就叫做动态绑定。

即调用向上转型的引用里面的方法,如果子类中也有返回类型,方法名称,传入参数完全一样的方法,那么将会调用子类的方法

方法重写与方法覆盖

方法重写

在上面我们看到子类中有方法返回类型,方法名称,传入参数与父类中完全一样,这样的行为就叫做方法的重写。

方法重写要注意几点:

1.重写是发生在子父类中的,在同一个类里面只支持方法重载。重写需要保证方法名称,传入参数要完全一样,返回类型要兼容。

2.返回类型必须要兼容,什么意思?就是子类中返回的类型必须要和父类返回的类型具有继承的关系或者完全和父类一致。

(这就用到了我们上面的向上转型的知识了,要记住,java里面子类是可以随意转换成父类的,也就是你可以把子类看成是和父类一样的类,但是反过来就不行了,你不能把一个父类看成一个子类。要理解这点,就能理解java中很多地方都支持子类转父类的操作。)

3.private,static,final修饰的父类方法无法被重写。

4.子类的方法的访问权限不能低于父类的方法的访问权限。

5.我们可以使用注解来对重写进行检查。具体如下面代码

image.png

要注意,注解并不是注释,如果你的重写有错误,那么注解是会报错的。

方法重载

方法重载的规则是 方法名称要相同,传入参数要不同,返回类型不做要求。

方法重载既可以在同一个类中发生,也可以在子父类中发生。

重载和重写的区别我们从字面意思就能知道,重载,说明原来的方法还在,重写,说明原来的方法以及被覆盖了。这也就是为什么动态绑定的时候我们调用向上转型的父类引用,调出来的却是子类的方法,因为子类已经重写了父类的方法,当我的对象实际上就是子类的时候,那么它就只会调用子类重写的方法。

下面给出代码的例子

image.png

认识多态

有了上面的知识储备之后,我们就可以来使用多态的思想来设计一些程序。

具体一点就是我们可以写一些只关注父类的代码,但其实可以由不同的子类传入(这就是向上转型嘛),然后调用对应的方法以后,会调用到各个子类重写的方法(这就是动态绑定嘛),这样就可以形成一组代码,多种表现形式的效果,这就是多态

下面给出一个具体的简单例子来帮助理解

image.png

image.png

这样我们就简单地完成了一个多态的设计,如果能理解上述代码,相信你也一定对java里面的多态有所了解了。

抽象类

要讲抽象类,让我们来回顾一下上篇博客中所讲的多态吧继承与多态

image.png

image.png

我们发现,在实现这样一个多态思想的代码的时候,父类Worker好像啥都没做,主要的打印工作其实是由各个子类里的work函数完成的,因此,我们可以对父类进行一个更详细的描述,将父类这样没有发生实际作用的work函数声明为抽象函数,那么包含抽象函数的类就叫做抽象类。

注意:无论是抽象类还是抽象方法都是用abstract来声明,含有抽象方法的类一定是抽象类,但是抽象类也可以不含有抽象方法。

下面给出代码实例

image.png

要注意两点:

1.抽象类是不能被实例化的。

2.抽象方法是没有方法体的

3.如果一个类继承了一个抽象类(如果这个抽象类还继承了另一个抽象类),那么这个类就要实现所有的抽象方法,否则,就将这个类也声明为抽象类

抽象类存在的最大意义就是被继承,因为抽象类是不能被实例化的,如果我们在后面的代码中不小心实例化了,那么编译器就会报错,这样就能达成一个检验的作用。因此我们要给予每个类最符合它们需求的限制,让我们的代码变得更加安全。

接口

接口,你可以理解为100%的抽象类,因为抽象类里面我们是可以包含普通方法的,但是接口里面的方法全部默认为抽象方法,接口里面的字段全部默认为public static final类型。接口的关键字是interface ,子类来实现(继承)接口使用关键字implements

下面给出具体的代码实例

image.png

image.png

那么实现接口有什么好处呢?

好处就是让程序员不再去关注类是什么类型,而是去关注这个类是否实现了我想要的接口,如果实现了,我就可以用,根本不用管这是什么类。

另外要注意,接口可以继承接口,一个类可以实现多个接口,但只能继承一个父类。

小结

对于抽象类与接口的认识也就差不多了,要注意,抽象类啊,接口啊这些东西都是为了服务多态这样一种灵活的设计方式。因此在我们使用多态去设计一些代码时,我们就可以尝试使用抽象类或者接口。

如果你对java里面的继承与多态的思想以及代码实现已经有所了解了,那么这篇文章想要传达的知识也就完成了。

今日份分享已结束,请大家多多包涵和指点!

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享