
3.3 this和super变量
面向对象程序设计体系的继承性会出现变量和方法的隐藏和覆盖等现象,为避免访问变量和调用方法出现二义性,在Java语言体系中设计了this和super两个变量。
关键字this和super是作为两个变量被应用的,更确切地说是两个“指针”变量,this指向当前类对象,super指向父类对象。当需要访问或调用当前类对象的变量或方法时,使用this变量,当需要访问或调用当前类的父类对象的变量或方法时,使用super变量。
3.3.1 this变量
this变量是针对访问或调用当前类对象的变量或方法而言的,this变量可作为当前类对象使用,其访问变量和调用方法的作用域为整个类。this变量使用的语法格式为:

【示例3-17】 通过this变量访问类中变量和调用类中方法的Java演示程序。

this变量是一个特殊的实例值,它用来在类中一个成员方法内部指向当前的对象。在this使用的语法格式中,this访问的变量和调用的方法实际上是表达式中的一个元素,由this构成的语句实现的是一种操作,因此,应该在方法体中完成,但是this变量不能使用在静态方法体中,因为this不是静态变量。例如,不能在静态的main()方法中使用this变量。
当在类中声明的变量与在方法中声明的变量具有相同的名字时,由于两个同名变量的作用域是不同的,因此,在方法体中使用this可以访问整个类作用域的变量。
【示例3-18】 this作用域演示的Java程序。

当在类中声明的变量与在方法的形式参数列表中声明的变量具有相同的名字时,在方法体中使用this将访问变量指向类声明的变量。
【示例3-19】 使用this避免二义性的Java演示程序。

this的另一个用途是调用当前类的构造方法,其语法格式为:

该应用形式只针对类的构造方法,其使用也在构造方法体内,并且是构造方法体内的第一行语句,this可调用当前类的带输入参数和无输入参数的构造方法。
【示例3-20】 使用this调用当前类构造方法的Java演示程序。

上述程序的原意是无论在什么情况下都需要在构造方法中为x变量赋予初始值,带输入参数的构造方法并非默认的构造方法,当该类需要有一个默认构造方法(用于继承等),同时又要求为x变量赋予初始值时,则在默认构造方法中使用this指定调用一个带输入参数的构造方法;当使用其他构造方法创建对象并为x和y变量赋予初始值时,则可通过this调用默认的构造方法。
3.3.2 super变量
super变量是在当前类中访问或调用其父类对象的变量或方法的。super变量可作为当前类的父类对象使用,super访问的是父类非private变量和调用的是父类非private方法。super变量使用的语法格式为:

【示例3-21】 通过super变量访问直接父类中变量和调用直接父类中方法的Java演示程序。

super变量也是一个实例值,用来在子类中一个成员方法内部指向当前类的父类对象,在super使用的语法格式中,super访问的变量和调用的方法实际上是表达式中的一个元素,由其构成的语句实现的是一种操作,因此,super操作应该在子类的方法体中实现。
有继承关系的子类和父类都存在着变量、方法的隐藏和覆盖等现象,使用super和this可分别操作隐藏和被隐藏、覆盖和被覆盖的变量和方法,super实现了访问在父类中被隐藏的变量和调用被覆盖的方法。
【示例3-22】 通过super访问在父类中被隐藏变量和调用被覆盖方法的Java演示程序。

在子类中,通过AccessSuper()方法访问了父类被隐藏的s变量和调用了父类被覆盖的printMethod()方法。
super的另外一个用途是在子类的构造方法中调用直接父类的构造方法,其语法格式为:

super的应用形式也是只针对类的构造方法的,其使用在子类的构造方法体内,并且是构造方法体内的第一行语句,super可调用直接父类的带输入参数和无输入参数的构造方法,例如示例3-23。
【示例3-23】 通过super调用直接父类构造方法的Java演示程序。

在一般情况下,当父类定义了构造方法时,在继承的子类构造方法中应先调用父类的构造方法实现父类对象的创建和初始化。