this关键字
this算是Java里面比较复杂的关键字,因为this的使用形式上决定了它的灵活性,在程序里,使用this可以实现以下三类结构的描述:
- 当前类中的属性:this属性
- 当前类中的方法(普通方法、构造方法):this()、this.方法名称();
- 描述当前对象
使用this调用当前的属性
通过现在的分析发现,利用构造方法或者是setter方法都可以进行类的属性的赋值,但是在进行赋值的时候,之前采用的是如下的定义形式:
class Person{
private String name;
private int age;
public Person(String n,int a){
name = n ;
age = a ;
}
public void tell(){
System.out.println("姓名:"+name+",年龄:"+age);
}
}
public class JavaDemo{
public static void main(String args[]){
person per = new person("王武",38);
per.tell();
}
}
但是在这个时候,在构造方法定义的过程之中会发现有一点问题:
public Person(String n,int a){
name = n ;
age = a ;
}
这个问题出现在参数名称上,可以发现,此时构造方法中两个参数的目的是为了类中的name或age属性的初始化,但是现在却发现此时代码n和a参数名称不好。
如果说现在讲构造方法中的参数名称修改为name和age,那么无法进行属性的正常设置
在Java程序之中,{}是作为一个结构体的边界符,那么在程序里面进行变量(参数、属性)使用的时候,都会以大括号为一个查找边界。所以按照就近取用的原则,此时的构造方法并没有访问类中的属性,为了明确的标记处类中的属性与参数的区别,往往会在属性前追加一个this,表示本类属性。
在以后所编写的程序代码中,只要是访问本类中属性的值,一定要加上this实现访问
使用this调用方法
除了调用属性之外,this也可以实现方法的调用,但是对于方法的调用就必须考虑构造与普通方法:
- 构造方法调用(this()):使用关键字new实例化对象时才会调用构造方法
- 普通方法调用(this.方法名称()):实例化对象产生之后就可以调用普通方法
调用类中的普通方法:
class Person{
private String name;
private int age;
public Person(String name,int age){
this.setName(name);
setAge(age);//加与不加都表示本类方法
}
public void tell(){
System.out.println("姓名:"+name+",年龄:"+age);
}
public void setName(String name){
this.name = name;
}
public void setAge(int age){
this.age = age;
}
public String getName(){
return this.name;
}
public int getAge(){
return this.age;
}
}
public class JavaDemo{
public static void main(String args[]){
person per = new person("王武",38);
per.tell();
}
}
除了普通的方法调用,还需要进行构造方法的调用,对于构造方法的调用,肯定是要放在构造方法中执行,现在假设说类中一共定义有三个构造方法,但是要求不管调用哪个构造方法,都执行一行输出语句“一个新的person类的对象实例化”
传统方法实现:
class Person{
private String name;
private int age;
public Person(){
System.out.println("****一个新的person类对象实例化了");
}
public Person(String name){
System.out.println("****一个新的person类对像实例化了");
this.name = name;
}
public Person(String name,int age){
System.out.println("****一个新的person类对像实例化了");
this.name = name;
this.age = age;
}
public void tell(){
System.out.println("姓名:"+name+",年龄:"+age);
}
public void setName(String name){
this.name = name;
}
public void setAge(int age){
this.age = age;
}
public String getName(){
return this.name;
}
public int getAge(){
return this.age;
}
}
public class JavaDemo{
public static void main(String args[]){
person per = new person("王武",38);
per.tell();
}
}
要想评价一个代码的好坏:
- 代码结构可以重用,提供的是中间独立的支持;
- 我们的目标是没有重复的代码
class Person{
private String name;
private int age;
public Person(){
System.out.println("****一个新的person类对象实例化了");
}
public Person(String name){
this();//调用本类无参构造
this.name = name;
}
public Person(String name,int age){
this(name);//调用单参构造
this.age = age;
}
public void tell(){
System.out.println("姓名:"+name+",年龄:"+age);
}
public void setName(String name){
this.name = name;
}
public void setAge(int age){
this.age = age;
}
public String getName(){
return this.name;
}
public int getAge(){
return this.age;
}
}
public class JavaDemo{
public static void main(String args[]){
person per = new person("王武",38);
per.tell();
}
}
对于本类方法的互相调用,需要注意以下几点重要的问题:
- 构造方法必须在实例化新对象的时候调用,所以this()的语句只能放在构造方法的首行;
- 构造放啊法互相调用时请保留有程序的出口,别形成死循环!
构造方法互相调用的案例:
现在要求定义一个描述有员工信息的程序类,该类中提供有:编号,姓名、部门、工资,在这个类之中提供有四个构造方法。
- 无参构造:编号定义为1000,姓名定义为无名氏
- 单参构造:传递编号,定义为“新员工”,部门定义为“未定”,工资为0
- 三参构造:传递编号,姓名,部门,工资为2500
- 四参构造:所有的属性全部进行传递
class Emp{
private long empno;//员工编号
private String ename;//员工姓名
private String dept;//部门名称
private double salary;//基本工资
public Emp(){
this.empno = 1000;
this.ename = "无名氏";
}
public Emp(long empno){
this.empno = empno;
this.ename = "新员工";
this.dept = "未定";
}
public Emp(long empno,String ename,String dept){
this.empno = empno;
this.ename = ename;
this.dept = dept;
}
public Emp(long empno.String ename,String dept,double salary){
this.empno = empno;
this.ename = ename;
this.dept = dept;
this.salary = salary;
}
public String getInfo(){
return"雇员编号:" + this.empno +
"、雇员姓名:" + this.ename +
"、所在部门:" + this.dept +
"、基本工资:" + this.sal;
}
}
public class JavaDdemo{//主类
public static void main(String args []){
Emp emp = new Emp(7369L,"史密斯","财务部",6500.00);
System.out.println(emp.getInfo());
}
}
此时代码有重复,所以对Emp类进行简化定义:
class Emp{
private long empno;//员工编号
private String ename;//员工姓名
private String dept;//部门名称
private double salary;//基本工资
public Emp(){
this(1000,"无名氏",null,0.0);
}
public Emp(long empno){
this(empno,"新员工","未定",0.0);
}
public Emp(long empno,String ename,String dept){
this(empno,ename,dept,2500.00);
}
public Emp(long empno.String ename,String dept,double salary){
this.empno = empno;
this.ename = ename;
this.dept = dept;
this.salary = salary;
}
public String getInfo(){
return"雇员编号:" + this.empno +
"、雇员姓名:" + this.ename +
"、所在部门:" + this.dept +
"、基本工资:" + this.sal;
}
}
public class JavaDdemo{//主类
public static void main(String args []){
Emp emp = new Emp(7369L,"史密斯","财务部");
System.out.println(emp.getInfo());
}
}
代码的任何位置上都有可能重复,所以消除重复的代码是先期学习中最需要考虑的部分。