this
和
super
是
Java
中的两个比较特殊的关键字。
this
表示当前对象,而
super
表示父类对象,严格来说应该是子类从父类继承过来的部分,包括继承过来的成员变量和成员方法。这两个关键字用于
Java
类中自己的方法来访问自己的成员变量和自己的成员方法。本次内容介绍如何使用
this
和
super
,主要内容如下:
l 正常情况下如何访问成员变量和成员方法
l 什么时候需要使用 this 访问成员和成员方法
l 什么时候需要使用 super 访问变量和成员方法
l 如何使用 this 访问其他的构造方法
l 如何使用 super 访问父类的构造方法
下面分别介绍。
1 正常情况下如何访问成员变量和成员方法
正常情况下,访问某个对象的方法和属性,通过“对象名
.
属性名”或者“对象名
.
方法名”访问成员变量和成员方法。
例:
String name;
System.out.println(name.length());
如果是类自己的方法访问成员变量和成员方法,可以采用如下的方式(
setName
方法中的代码)。
例:
package
thisAndSuper;
public
class
Animal {
protected
String
id
;
protected
String
name
;
public
void
setName(String newname){
//
正常情况下,应该这样访问成员变量和成员方法
name
= newname;
print(
"
初始化名字
"
);
}
public
void
print(String message){
System.
out
.println(
"Animal--------"
+message);
}
}
这里再访问
name
属性和
print
方法的时候为什么没有给出对象名呢?因为在编写类的时候不知道对象的名字,因为对象在运行之后才会产生。
Name
属性和
print
方法应该属于哪个对象呢?应该是当前方法(
setName
)所属的对象,为了表示这个对象,
Java
中提供了
this
关键字用来表示当前对象。可以通过
this
访问所有的成员变量和成员方法。
2 什么时候需要使用 this 访问成员和成员方法
上面的代码中没有使用
this
访问
name
属性和
print
方法,实际上可以通过
this
访问,上面的
setName
方法可以写成下面的形式。
例:
public
void
setName(String newname){
this.
name
= newname;
this.print(
"
初始化名字
"
);
}
什么时候必须用
this
呢?
当局部变量与成员变量重名的时候必须使用
this
。例如,类中有成员变量
id
,而方法的参数中也有变量
id
。看下面的代码。
例:
public Animal(String id){
this .id = id;
}
如果直接写成
id=id
,赋值过程无效。但是不会有编译或运行错误,只是没有真正赋值。
3 什么时候需要使用 super 访问变量和成员方法
super
表示从父类继承来的成员变量和成员方法,
this
可以用来访问所有的成员变量和成员方法,包括从父类继承过来的成员变量和成员方法。什么时候必须使用
super
呢?
如果父类和子类有同名成员变量或成员方法,默认情况下访问的是子类的,如果希望访问从父类继承的成员,则必须通过
super
这种方式访问从父类继承过来的成员变量。
例:
public void setParentName(String name){
// 调用从父类继承过来的成员变量,如果父类和子类有同名成员变量,则必须通过这种方式访问从父类继承过来的成员变量
// super.name = name;
// 调用从父类继承过来的成员变量,父类中定义的私有的成员变量和方法是不能访问的
super .setName(name);
this .print("设置从父类继承过来的成员! ");
}
4 如何使用 this 访问其他的构造方法
this
还可以用来访问自己的构造方法。用法与调用其它方法不同。下面的代码展示了用法。
例:
public Animal(String id,String name){
// 调用自己的构造方法,必须放在方法中的第一行
this (id);
this .name = name;
}
注意:使用
this
调用自己的构造方法,必须放在构造方法中,并且必须是构造方法的第一行有效代码。
5 如何使用 super 访问父类的构造方法
要访问父类的构造方法需要使用
super
,用法与使用
this
访问自己的构造方法相似。
例:
public Dog(String id){
// 调用父类的构造方法
super (id);
}
public Dog(String id,String name){
// 调用父类的构造方法,必须放在方法中的第一行
super(id);
this .name = name;
}
注意:必须放在构造方法中,并且必须是构造方法中的第一行有效代码。
另外需要注意:必须调用父类构造方法,如果不写,系统会自动调用父类的无参数构造方法。如果父类没有参数构造方法,就会出错。
看看下面的代码会报什么错?
public class Animal{
protected String id;
public Animal(Stirng id){
this.id = id;
}
}
public class Dog extends Animal{
protected String name;
public Dog(String name){
this.name = name;
}
}
下面的例子展示了
this
和
super
的用法。
package thisAndSuper;
public class Animal {
protected String id;
protected String name;
public void setName(String newname){
// 正常情况下,应该这样访问成员变量和成员方法
name = newname;
print("初始化名字 ");
}
public Animal(String id){
this .id = id;
}
public Animal(String id,String name){
// 调用自己的构造方法,必须放在方法中的第一行
this (id);
this .name = name;
}
public void print(String message){
System.out .println("Animal--------"+message);
}
}
package thisAndSuper;
public class Dog extends Animal{
public String name;
public String x;
public void setName(String name){
// 调用自己的成员变量,或者从父类继承过来的成员变量
this .name = name;
// 调用从父类继承过来的成员方法,也可以使用 this.print(" 设置子类成员 ");
super .print("设置子类成员 "); //this.print(" 设置子类成员 ");
}
public void setParentName(String name){
// 调用从父类继承过来的成员变量,如果父类和子类有同名成员变量,则必须通过这种方式访问从父类继承过来的成员变量
// super.name = name;
// 调用从父类继承过来的成员变量,父类中定义的私有的成员变量和方法是不能访问的
super .setName(name);
this .print("设置从父类继承过来的成员! ");
}
public Dog(String id){
// 调用父类的构造方法
super (id);
}
public Dog(String id,String name){
// 调用父类的构造方法,必须放在方法中的第一行
super (id);
this .name = name;
}
public void print(String message){
System.out .println("Dog--------"+message);
}
}