面向对象三大特性之——继承
一、引言
此篇文章来自一个初学Java不久的学生,内容的用词、深度、广度甚至部分理解不够到位,再加上Markdown语法的不熟练,所以排版不够美观。但还是希望有疑问的读者能够读完全文,大家遇到问题可以一起交流。谢谢!
二、作者初识继承
最开始接触继承是在Java知识体系里面的。我最开始的理解,继承是Java语法里面的一个特性。其实这是错误的,Java属于面向对象编程语言的知识体系,而继承则是属于面向对象知识体系的,并且是它的三大特性之一。其他的两个是封装和多态。
三、继承正文
一、基本概念
一、什么是继承
面向对象的编程允许你从已经存在的类中定义新的类(我在接下来的内容中将它引申为你和你的父亲,你在你父亲的基础上,开始了你的新生命)。在Java术语中,如果类C1扩展自另一个类C2,那么将C1称为次类(子类、扩展类、派生类),C2称为超类(父类、基类)。一般用于是父类和子类。
二、继承的使用场景
在定义不同的类时,但是又有很多相同的属性和方法,抽取其中的公共部分,就可以使用继承来减少代码量,以此达到代码的复用,并且达到程序后期的易维护的特点。
三、继承的优缺点
优点:减少代码量,实现代码复用。子类从它的父类中继承可访问的数据域和方法,还可以添加新数据域和新方法。
缺点:前一篇文章讲到了,面向对象设计思想里面的:高内聚低耦合。继承与耦合性发生了冲突。因为父类的数据域和方法的变化,也会带动子类的变动。
二、成员特点
一、构造方法
1.调用父类的构造方法
构造方法分为:1)无参构造方法:类名()、带参构造方法:类名(参数列表)
调用父类构造方法为:1)无参构造方法:super()、带参构造方法:super(参数列表)
注意:构造方法语句,必须出现在子类构造方法的第一行,这是显式调用父类构造方法的唯一方式。默认的调用构造方法为隐式调用,隐式调用只能调用无参构造方法。
1)隐式调用无参构造方法:
2)显式调用无参构造方法:
3)显式调用带参构造方法:
4)在定义了带参构造后,隐式调用无参构造方法会出错
2.构造方法链
在任何情况下,构造一个类的实例时,将会沿着继承链的所有父类的构造方法前行。当构造一个子类的对象时,子类狗仔方法会在完成自己的任务之前,首先调用它的父类的构造方法。如果父类继承自其他类,那么父类构造方法又会在完成自己的任务之前,调用它自己的父类的构造方法。这个过程持续到沿着这个继承体系机构的最后一个构造方法被调用为止。这就是构造方法链。
二、成员变量
this:相当于调用对象的引用
super:指这个super关键字所在的类的父类
this、super综合理解:
综合理解的内存解释(笔者画图画了半个小时,发现不堪入目,所以还是口述):这是内存的基本框架
程序运行步骤:
(1)主方法进栈,且在栈区里面定义Apple类型的变量a,用于接收地址值
(2)在内存堆里面声明一块内存地址,用来存放Apple()方法
(3)当系统运行到Apple()时,发现它继承自Fruits类,便在自己的内存空间里面再开辟一块地址空间给父类
(4)由于Apple子类中显式的调用了父类的构造方法,所以代码转到Fruits的带参构造方法
(5)执行Fruits带参构造代码,打印相应语句。
(6)this.num代表调用这个类的对象,即父类在子类开辟的内存空间里面,又开辟的一块空间地址,即this指向的就是父类的地址空间的值,即在父类的地址空间里面指向它的成员变量值,即为20
(7)num值为父类方法的局部变量,即输出的值为带参构造方法的参数值30
(8)然后执行Apple()方法中显式调用父类方法的后面语句
(9)this.num代表调用这个类的对象,即main方法里面a值,即为最开始的子类再堆内存里面开辟的地址空间,即num的值为Apple()方法的成员变量5
(10)super.num为Apple()的继承类的num值,Apple类继承自Fruits类,即super.num的值为父类的成员变量20
(11)子类Apple()方法运行结束,代码的运行回到主函数,打印a.num,即子类在堆地址里面的内存空间,即子类的成员变量,值为5
三、成员方法
答:在定义一个方法的时候,应该做到两个明确。
(1)返回值类型
(2)参数列表
这两个点统称为方法的签名。
1.重载
重载意味着使用着与类相同的名字,有着不同的参数,而且参数的列表是成员变量里面的零个、一个或多个,而且重载方法是没有返回值的。
2.重写
在子类中提供一个对父类方法的新的实现。即对父类里面的方法进行重新书写,通常带有关键字@Override
3.联系和区别
(1)方法的重写发生在通过继承而相关的不同类中;方法重载可以发生在同一个类中,也可以发生在由于继承而相关的不同类中
(2)方法重写具有同样的方法名称和返回值类型;方法的重载具有相同的名字,但是不同的参数列表。如果父类定义的方法是带有返回值的方法,那么你也可以根据是否有返回值来判断眼前的这个方法是重写还是重载。