java 对象实例化过程中的多态特性解析
java 对象实例化过程中的多态特性
执行对象实例化过程中遵循多态特性 ==> 调用的方法都是实例化的子类中的重写方法,只有明确调用了super.xxx关键词或者是子类中没有该方法时,才会去调用父类相同的同名方法。
通过案例说明
package com.njau.test1; class test { public static void main(string[] args) { system.out.println(new b().getvalue()); } static class a { protected int value; public a (int v) { setvalue(v); } public void setvalue(int value) { this.value= value; } public int getvalue() { try { value ++; return value; } finally { this.setvalue(value); system.out.println(value); } } } static class b extends a { public b () { super(5); setvalue(getvalue()- 3); } public void setvalue(int value) { super.setvalue(2 * value); } } }
通过上述代码
始终明确调用的方法必须是实例化子类中重写的方法。
首先,在main函数中,【new b()】new了一个b类的实例化对象,在实例化对象时,调用了b类中的构造函数,执行【super(5)】,也就是public a(int v)------>setvalue(v),由于调用的方法必须是实例化子类中重写的方法的原则。因此,这里调用的是b类中的setvalue(v)方法,此时b实例的value值设置为2 x 5 = 10,后执行super.setvalue(10),将value=10的值存储起来。
执行完super(5)后,执行构造函数中的【setvalue(getvalue()- 3)】中【getvalue()】,由于b类中没有getvalue()方法,则调用父类(a类)中的getvalue()方法,value++所得到的值为11,并存储在value中(先执行finally中的部分,后执行try中的return),在finally中,调用了【this.setvalue(value)】,由于调用的方法必须是实例化子类中重写的方法的原则,调用的是b类中的setvalue(v)方法,此时b实例的value值设置为2 x 11= 22,之后执行system.out.println(value)
即在控制台上打印22
执行完finally中的部分,后执行try中的return,将value++执行后,存储在value中的11,return回去;执行【setvalue(getvalue()- 3)】
即:setvalue(8)
执行setvalue(8)时,由于调用的方法必须是实例化子类中重写的方法的原则,则调用b类中的setvalue(v)方法,此时b实例的value值设置为2 x 8= 16;此时b类中的构造函数执行结束。
在实例化对象以后,执行【new b().getvalue()】,由于b类中没有getvalue()方法,则调用父类(a类)中的getvalue()方法,value++所得到的值为17,并存储在value中,在finally中,调用了【this.setvalue(value)】,由于调用的方法必须是实例化子类中重写的方法的原则,调用的是b类中的setvalue(v)方法,此时b实例的value值设置为2 x 17= 34,之后执行system.out.println(value)
即在控制台上打印34
执行完finally中的部分,后执行try中的return,将value++执行后,存储在value中的17,return回去;执行【system.out.println(new b().getvalue())】
即在控制台上打印17
value值的变化过程,仅解释实例化对象时,构造函数中:super(5)与setvalue(getvalue()+3)两部分。图中两条线,起点分别为【new b()】与【setvalue(getvalue()+3)】:
执行结果为:
java对象的三个特性(封装、继承、多态)
类(类型)和对象:对象是独一无二的。对象有其所属之类型。对象是类型的一个具体的实例。
创建编写一个 class :定义一个类型。类型是编写出来的,即使程序不运行,类型已然存在。
对象:对象是new出来的,在程序运行期间new出来的,存在于内存中(堆中 )。如果程序未运行,则对象不存在。
对象的三大特性:
1.封装
1.1 把本属于某个类型的成员属性(静态特性)和职责(动态特性)定义到一个类中。
1.2 访问权限控制:使用权限访问修饰符控制成员(属性和方法)的访问(可见性)。
-
private
:最小访问权限,仅限类的内部可以访问。 -
<无修饰符>
:包修饰符,友好访问修饰符,类内,包内可以访问。 -
protected
:类内,包内,子类可以访问。 -
public
:类内,包内,子类,包外都可以访问。
类的两大成员:
1.属性:有默认值,0 0.0 false '\0' null。引用类型的默认值是null值。
2.方法:方法中,可以访问成员属性。
构造方法:
用于构造对象(对对象进行成员属性初始化),构造对象的过程可能简单,也可能复杂。
- 和类同名。语法:new 构造方法(参数列表)
- 无返回值。其作用仅为构造对象。
- 构造方法可以重载。
this关键字:
- 访问当前对象的属性和方法。
- this(参数列表),只能放在构造方法的第一行,并且只能单独使用。
- 当方法的参数和成员属性名称冲突的时候,可以使用this进行区分。
2.继承
2.1 为什么要继承:消除重复。子类可以继承父类的某些成员。
2.2 extends 关键字:扩展。一个类只能继承一个父类。如果没有指定父类的话,则默认继承自object类。object类是根类型,终级类,没有父类。其它一切引用类型都是直接或间接继承自object类型。
2.3 什么成员可以被继承?1. 私有成员不能被继承。2. 构造方法不能被继承。
2.4 子类对象构造的过程:按照继承的顺序,递归创建各类型的状态值。
3.多态
同一个类型所展现出的行为或属性的多种形态。
使用父类(祖先类、接口)的引用指向子类(派生类,实现类)的对象。
多态的使用场景:某些场景,只希望关注某些(不同的具体类型)类型的共性(祖先类,接口),而忽略其它独特的特性。
final:
- 修饰类,表示类不可被继承。
- 修饰方法,表示方法不能被重写。
- 修饰成员属性,或者普通变量,表示值不可修改。
static:静态的
- 一旦属性和方法,添加了static关键字,表示属性和方法是属于类的,而不是属于某一个具体的对象的。
- 通过“类名.静态成员”来访问,而无须先创建对象。
抽象类:
- 当定义一个类时,如果某个方法暂时不便实现,或者无法实现,或者不适合实现,或者希望具体的子类来提供实现,可以使用abstract关键字来修饰此方法,表示抽象方法,抽象方法无需提供实现。
- 当一个类中存在抽象方法时,类必须定义成抽象类。但是,一个抽象类中可以没有抽象方法。
- 抽象类不能实例化,但可以定义构造方法。
- 抽象类是类,拥有一切类的特性,除了不能实例化。
接口:
- 接口不是类。但是接口和抽象类类似。
- 接口中的方法全都是公有的抽象方法。jdk8之前。
- 接口中的属性,都是公有的静态的最终的。
- 接口需要类来提供实现。implements关键字。一个类可以实现多个接口,相当于将所有这些接口的方法提供实现。
- 接口可以继承接口,使用 extends 关键字。
- 接口也可以使用多态特性,使用接口的引用指向实现类的实例。
- 接口的主要目的(作用)就是多态。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持。
推荐阅读
-
Java实例化一个抽象类对象的方法教程
-
java 序列化对象 serializable 读写数据的实例
-
荐 浅谈Java中类和对象的初始化、实例化以及方法重载的底层机制
-
Java学习笔记二十五:Java面向对象的三大特性之多态
-
第十一天-Java继承/多态特性-方法重写/抽象类/适配器/对象运行时的多态/
-
阿里Java学习路线:阶段 1:Java语言基础-Java语言高级特性:第22章:反射应用案例:课时101:反射实例化对象
-
一文带你了解java面向对象的三大特性:继承、封装、多态
-
java 对象实例化过程中的多态特性解析
-
Effective Java笔记第一章创建和销毁对象第四节通过私有构造器强化不可实例化的能力
-
java面向对象的封装继承多态特性