问题引入:
public class EmployTest {
public static void main(String[] args) {
Employee e1 = new Employee();
e1.setName("小明");
e1.setSalary(100);
System.out.println("名字:"+e1.getName()+" 薪资:"+e1.getSalary());
}
}
class Employee {
private String name;
private int salary;
public Employee() {
}
public Employee(String n, int s) {
name = n;
salary = s;
}
public String getName(){
return name;
}
public int getSalary(){
return salary;
}
public void setName(String name) {
name = name;
}
public void setSalary(int salary) {
salary = salary;
}
}
输出结果:(为什么?????)
名字:null 薪资:0
试验一:我们在 setName方法
和 setSalary方法
中添加打印 name
和 salary
变量的语句
public static void main(String[] args) {
Employee e1 = new Employee();
System.out.println("名字:"+e1.getName()+" 薪资:"+e1.getSalary());
e1.setName("小明");
e1.setSalary(100);
System.out.println("名字:"+e1.getName()+" 薪资:"+e1.getSalary());
}
public void setName(String name) {
System.out.println("name = " + name);
name = name;
}
public void setSalary(int salary) {
System.out.println("salary = " + salary);
salary = salary;
}
再次运行,输出结果为
名字:null 薪资:0
name = 小明
salary = 100
名字:null 薪资:0
从打印结果来看,当我们 new
出一个 Employee对象
时,成员变量 name
和 salary
都是默认值的。经过setName方法
和 setSalary方法
也没有改变成员变量的值,那就说明变量冲突了。或者说 name = name;
salary = salary;
这两句代码其实本质上就是 name =null
salary = 0
。虽然参数传进来了,但是由于名字的原因造成了访问冲突。
试验二:如果我们把方法的参数换个名字呢?
public void setName(String n) {
System.out.println("name = " + name);
System.out.println("n = " + n);
name = n;
}
public void setSalary(int s) {
System.out.println("salary = " + salary);
System.out.println("s = " + s);
salary = s;
}
输出结果为:
名字:null 薪资:0
-----------手动分割线----------
name = null
n = 小明
-----------------------------
salary = 0
s = 100
-----------手动分割线----------
名字:小明 薪资:100
小结:
既然改变一个名称就可以运行正确了,那为什么还需要this关键字???难道你不觉得起变量名字很难吗(来自萌新的恐惧),甚至都有了https://unbug.github.io/codelf/这种帮你给变量起名的网站。问一下 this.salary = salary; 这种风格它不香吗? 而且IDEA快捷键的getter方法和setter方法和构造器都是这样,难不成还要自己手动改?如果你有时间,… 加油
正文
this关键字
作用一:this关键字可以让程序知道你要明确的访问一个类的成员变量,与局部变量明显的分开来。
当我们添加上this关键字后
public class EmployTest {
public static void main(String[] args) {
Employee e1 = new Employee();
System.out.println("名字:"+e1.getName()+" 薪资:"+e1.getSalary());
e1.setName("小明");
e1.setSalary(100);
System.out.println("名字:"+e1.getName()+" 薪资:"+e1.getSalary());
}
}
class Employee {
private String name;
private int salary;
public Employee() {
}
public Employee(String n, int s) {
this.name = n;
this.salary = s;
}
public String getName(){
return name;
}
public int getSalary(){
return salary;
}
public void setName(String name) {
this.name = name;
}
public void setSalary(int salary) {
this.salary = salary;
}
}
输出结果
名字:null 薪资:0
名字:小明 薪资:100
作用二:通过this关键字调用成员方法——this.方法名字
在Employee类中,添加两个方法
public static void main(String[] args) {
Employee e1 = new Employee();
e1.a();
e1.b();
}
public void a(){
System.out.println("这是a方法...");
}
public void b(){
this.a();
a(); //与this.a()没有区别
System.out.println("这是b方法");
}
输出结果:
这是a方法...
这是a方法...
这是b方法
作用三:在构造方法中访问构造方法this([参数…])
public class EmployTest {
public static void main(String[] args) {
Employee e1 = new Employee();
Employee e2 = new Employee("小明", 100);
}
}
class Employee {
private String name;
private int salary;
public Employee() {
System.out.println("这里是无参构造");
}
public Employee(String name, int salary) {
this(); //调用无参构造
this.name = name;
this.salary = salary;
}
{....}
}
输出结果:
这里是无参构造
这里是无参构造
分析:
在创建第一个Employee对象e1时,就会调用了无参构造。
在创建第二个Employee对象e2时,传入了两个参数,调用了有参构造,而里面又调用了无参构造。
注意事项:
- 不能在一个类中的两个构造方法中使用this()互相调用。——这样会造成死循环
- 在构造方法中使用this()调用构造方法的语句必须位于第一行,而且只能出现一次。
- 只能在构造方法中使用this()调用其他的构造方法,不能在成员方法中使用。
补充
添加一个Alitter继承Employee
public static void main(String[] args) {
System.out.println("-----------------------");
Alitter a1 = new Alitter();
Alitter a2 = new Alitter("小A", 300);
}
class Alitter extends Employee{
private String aName;
private int aage;
public Alitter() {
System.out.println("这里是AlitterEmployee无参构造");
}
public Alitter(String aName, int aage) {
System.out.println("这里是AlitterEmployee有参构造");
this.aName = aName;
this.aage = aage;
}
}
输出结果:
-----------------------
这里是Employee无参构造
这里是AlitterEmployee无参构造
这里是Employee无参构造
这里是AlitterEmployee有参构造
子类构造方法默认调用了父类的无参构造方法,先调用父类的无参构造方法,然后在调用子类的无参构造方法,从上到下