关于this和super
this的用法:
把当前对象的引用作为参数传递给另一个方法。如obj.f(this);
this.属性名
如果方法里的局部变量(包括形参)和成员变量同名,而我们的程序的目的是要访问被覆盖后的成员变量,则必须使用this.变量名。
比如说定义一个人类;
class person{
String name;
person(String name){
this.name=name;
}
}
class Test{
public static void main(String[] args){
person a=new person("李明璐");
System.out.println(a.name);
}
}
在这里的构造参数是person(String name),这里的形参数name与我们的成员属性name同名,因此在·构造函数里我们要this.name=name;否则这里的成员变量会变成 默认值null如果形参不是name而是其他的名字比如说n,那我们这里就不需要这样做。
this.方法名
这个状态才能让this起到最大的作用
this关键字的最大的作用就是让类中的一个方法来访问类里的另一个方法或实例变量
this.方法名
this 关键字最大的作用就是让类中一个方法,访问该类里的另一个方法或实例变量。
例 2
假设定义了一个 Dog 类,这个 Dog 对象的 run( ) 方法需要调用它的 jump( ) 方法,Dog 类的代码如下所示:
/**
* 第一种定义Dog类方法
**/
Public class Dog{
// 定义一个jump()方法
publicvoidjump(){
System.out.println("正在执行jump方法");
}
// 定义一个run()方法,run()方法需要借助jump()方法
publicvoidrun(){
Dog d =newDog();
d.jump();
System.out.println("正在执行 run 方法");
}
}
使用这种方式来定义这个 Dog 类,确实可以实现在 run( ) 方法中调用 jump( ) 方法。下面再提供一个程序来创建 Dog 对象,并调用该对象的 run( ) 方法。
Public class DogTest{
Public stati cvoid main(String[]args){
// 创建Dog对象
Dog dog =newDog();
// 调用Dog对象的run()方法
dog.run();
}
}
在上面的程序中,一共产生了两个 Dog 对象,在 Dog 类的 run( ) 方法中,程序创建了一个 Dog 对象,并使用名为 d 的引用变量来指向该 Dog 对象。在 DogTest 的 main() 方法中,程序再次创建了一个 Dog 对象,并使用名为 dog 的引用变量来指向该 Dog 对象。
下面我们思考两个问题。
1)在 run( ) 方法中调用 jump( ) 方法时是否一定需要一个 Dog 对象?
答案是肯定的,因为没有使用 static 修饰的成员变量和方法都必须使用对象来调用。
2)是否一定需要重新创建一个 Dog 对象?
不一定,因为当程序调用 run( ) 方法时,一定会提供一个 Dog 对象,这样就可以直接使用这个已经存在的 Dog 对象,而无须重新创建新的 Dog 对象了。因此需要在 run() 方法中获得调用该方法的对象,通过 this 关键字就可以满足这个要求。
this 可以代表任何对象,当 this 出现在某个方法体中时,它所代表的对象是不确定的,但它的类型是确定的,它所代表的只能是当前类的实例。只有当这个方法被调用时,它所代表的对象才被确定下来,谁在调用这个方法,this 就代表谁。
将前面的 Dog 类的 run( ) 方法改为如下形式会更加合适,run( ) 方法代码修改如下,其它代码不变。
/**
* 第二种定义Dog类方法
**/
// 定义一个run()方法,run()方法需要借助jump()方法
publicvoidrun(){
// 使用this引用调用run()方法的对象
this.jump();
System.out.println("正在执行run方法");
}
从第一种 Dog 类定义来看,在 Dog 对象的 run( ) 方法内重新创建了一个新的 Dog 对象,并调用它的 jump( ) 方法,这意味着一个 Dog 对象的 run( ) 方法需要依赖于另一个 Dog 对象的 jump( ) 方法,这不符合逻辑。
第二种 Dog 类定义是当一个 Dog 对象调用 run( ) 方法时,run( ) 方法需要依赖它自己的 jump( ) 方法,与第一种定义类的方法相比,更符合实际情形。
在现实世界里,对象的一个方法依赖于另一个方法的情形很常见,例如,吃饭方法依赖于拿筷子方法,写程序方法依赖于敲键盘方法。这种依赖都是同一个对象两个方法之间的依赖。因此,Java 允许对象的一个成员直接调用另一个成员,可以省略 this 前缀。也就是说,将上面的 run( ) 方法改为如下形式也完全正确。
publicvoidrun(){
jump();
System.out.println("正在执行run方法");
}
大部分时候,一个方法访问该类中定义的其他方法、成员变量时加不加 this 前缀的效果是完全一样的。
注意:对于 static 修饰的方法而言,可以使用类来直接调用该方法,如果在 static 修饰的方法中使用 this 关键字,则这个关键字就无法指向合适的对象。所以,static 修饰的方法中不能使用 this 引用。并且 Java 语法规定,静态成员不能直接访问非静态成员。
省略 this 前缀只是一种假象,虽然程序员省略了调用 jump() 方法之前的 this,但实际上这个 this 依然是存在的。
this()访问构造方法
this()作为方法用于一个构造函数里是调用另一个构造函数,不能用于其他成员函数
this(x,y);x对第一个成员变量赋值,y对第二个成员变量赋值
super访问父类成员
super表示当前对象的直接父类对象引用,使用super可以访问被子类重新声明而隐藏的父类的变量和方法(意思就是子类里有与父类相同名字的变量或者方法‘重载了’)
class person{
String name;
int age;
person(String name,int age){
this.name=name;
this.age=age;
}
}
class student extends person{
int grade;
student(String name,int age,int grade){
super(name,age);//调用父类的构造函数
this.grade=grade;
}
public String toString(){//注意这里的toString()要使用public访问控制否则无法覆盖Object类的toString()方法
String s="Name: "+name+"\n";//这里想要输出\n就只需要在"\\n"即可
s+="Ages: "+age+"\n";
s+="Grade: "+grade+"\n";
return s;
}
}
class Test{
public static void main(String[] args){
student s=new student("李明璐",19,2);
System.out.print(s.toString());
}
}
C:\Users\86183\java>java Test
Name: 小李
Ages: 19
Grade: 2
super调用父类的构造方法和this一样必须放在第一句