您当前的位置: 首页 > 学无止境 > 心得笔记 网站首页心得笔记
【第5章:面向对象基础】_this关键字
发布时间:2020-12-09 18:03:28编辑:雪饮阅读()
当形参与类的属性同名时
对于如下程序:
class Person{
private String name;
private int age;
public Person(String n,int a){
name=n;
age=a;
}
public String getInfo(){
return "姓名:"+this.name+",年龄:"+age;
}
}
public class Hello{
public static void main(String args[]){
System.out.println(new Person("kasumi",18).getInfo());
}
}
D:\>javac Hello.java
D:\>java Hello
姓名:kasumi,年龄:18
D:\>
这是一个很普通的程序,看起来没有什么问题,但是对于其构造参数n和a来说不够明确,如果构造参数分别也是name和age,那么和类的name与age就正好一一对应,且对于调用者来说一眼就知道要传参数的含义。于是程序就变成如下
class Person{
private String name;
private int age;
public Person(String name,int age){
name=name;
age=age;
}
public String getInfo(){
return "姓名:"+this.name+",年龄:"+age;
}
}
public class Hello{
public static void main(String args[]){
System.out.println(new Person("kasumi",18).getInfo());
}
}
D:\>javac Hello.java
D:\>java Hello
姓名:null,年龄:0
D:\>
这里又会发现虽然形参看似更友好了,但是实际上实例化后name和age并没有在构造期间赋值成功。这是因为形参与类的属性相同时java发现有两个相同变量,那么就近原则(我理解为就近原则)下形参最近那么这里的程序可以理解为”形参name=形参name”,“形参age=形参age”,也即是对类的属性并没有进行构造,那么如果非要形参名和类的属性名相同,则需要借助this关键字,于是程序又变成这样
class Person{
private String name;
private int age;
public Person(String name,int age){
this.name=name;
this.age=age;
}
public String getInfo(){
return "姓名:"+this.name+",年龄:"+age;
}
}
public class Hello{
public static void main(String args[]){
System.out.println(new Person("kasumi",18).getInfo());
}
}
D:\>javac Hello.java
D:\>java Hello
姓名:kasumi,年龄:18
D:\>
这里this就代指了当前对象(类)的属性,所以运行结果是ok的。
构造函数中的this
假定有需求:一个类有多个构造,比如无参构造、有参构造、多参构造,现在要求无论调用那个构造都要记录一次实例化。
对于此需求的一般实现方法则如:
class Person{
private String name;
private int age;
public Person(){
System.out.println("新对象实例化");
}
public Person(String name){
System.out.println("新对象实例化");
this.name=name;
}
public Person(String name,int age){
System.out.println("新对象实例化");
this.name=name;
this.age=age;
}
public String getInfo(){
return "姓名:"+this.name+",年龄:"+age;
}
}
public class Hello{
public static void main(String args[]){
System.out.println(new Person().getInfo());
System.out.println(new Person("kasumi").getInfo());
System.out.println(new Person("kasumi",18).getInfo());
}
}
D:\>javac Hello.java
D:\>java Hello
新对象实例化
姓名:null,年龄:0
新对象实例化
姓名:kasumi,年龄:0
新对象实例化
姓名:kasumi,年龄:18
新对象实例化
姓名:kasumi,年龄:18
这样需求是实现了,但是从实现程序上会需要每个构造都重复执行一些代码。那么可以通过this关键字来改善下。于是程序又变成如下:
class Person{
private String name;
private int age;
public Person(){
System.out.println("新对象实例化");
}
public Person(String name){
this();
this.name=name;
}
public Person(String name,int age){
this(name);
this.age=age;
}
public String getInfo(){
return "姓名:"+this.name+",年龄:"+age;
}
}
public class Hello{
public static void main(String args[]){
System.out.println(new Person().getInfo());
System.out.println(new Person("kasumi").getInfo());
System.out.println(new Person("kasumi",18).getInfo());
}
}
D:\>javac Hello.java
D:\>java Hello
新对象实例化
姓名:null,年龄:0
新对象实例化
姓名:kasumi,年龄:0
新对象实例化
姓名:kasumi,年龄:18
这样也能实现需求并且比上面的实现方式友好些。这里需要注意下在当前类中用this调用构造函数不能是“this. Person()”这种方式,这样会报错如:
class Person{
private String name;
private int age;
public Person(){
System.out.println("新对象实例化");
}
public Person(String name){
this.Person();
this.name=name;
}
public Person(String name,int age){
this(name);
this.age=age;
}
public String getInfo(){
return "姓名:"+this.name+",年龄:"+age;
}
}
public class Hello{
public static void main(String args[]){
System.out.println(new Person().getInfo());
System.out.println(new Person("kasumi").getInfo());
System.out.println(new Person("kasumi",18).getInfo());
}
}
D:\>javac Hello.java
Hello.java:8: 找不到符号
符号: 方法 Person()
位置: 类 Person
this.Person();
^
1 错误
编译都编译不过去
另外还需要注意“this()只能用在构造函数中,且它必须是第一行语句!”
如:
class Person{
private String name;
private int age;
public Person(){
System.out.println("新对象实例化");
}
public Person(String name){
this.name=name;
this();
}
public Person(String name,int age){
this(name);
this.age=age;
}
public String getInfo(){
return "姓名:"+this.name+",年龄:"+age;
}
}
public class Hello{
public static void main(String args[]){
System.out.println(new Person().getInfo());
System.out.println(new Person("kasumi").getInfo());
System.out.println(new Person("kasumi",18).getInfo());
}
}
D:\>javac Hello.java
Hello.java:9: 对 this 的调用必须是构造函数中的第一个语句
this();
^
1 错误
又是编译都不通过
另外还需要注意这种方式实现需求虽然好,但是容易造成死循环,若不幸写成如下:
class Person{
private String name;
private int age;
public Person(){
this("repository",30);
System.out.println("新对象实例化");
}
public Person(String name){
this();
this.name=name;
}
public Person(String name,int age){
this(name);
this.age=age;
}
public String getInfo(){
return "姓名:"+this.name+",年龄:"+age;
}
}
public class Hello{
public static void main(String args[]){
System.out.println(new Person().getInfo());
System.out.println(new Person("kasumi").getInfo());
System.out.println(new Person("kasumi",18).getInfo());
}
}
D:\>javac Hello.java
Hello.java:8: 递归构造函数调用
public Person(String name){
^
1 错误
这样就会造成递归调用,陷入死循环。这块做的比php好,php如果这样写我记得好像是直接执行直到内存耗尽,java这里已经在编译期间就发现了问题。
this在类中指代类的当前实例化对象的地址,不同对象的地址不同
class Person{
public String getInfo(){
System.out.println("Person类 --> " + this);
return null;
}
}
public class Hello{
public static void main(String args[]){
Person per1=new Person();
Person per2=new Person();
System.out.println("per1 --> " + per1);
per1.getInfo();
System.out.println("per2 --> " + per2);
per2.getInfo();
}
}
D:\>javac Hello.java
D:\>java Hello
per1 --> Person@c17164
Person类 --> Person@c17164
per2 --> Person@1fb8ee3
Person类 --> Person@1fb8ee3
对象比较中this的作用
对于两个对象进行比较是否同一个对象,则非严谨的实现有如:
class Person{
private String name;
private int age;
public Person(String name,int age){
this.setName(name);
this.setAge(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 Hello{
public static void main(String args[]){
Person per1=new Person("natural",24);
Person per2=new Person("natural",24);
if(per1.getName().equals(per2.getName()) && per1.getAge()==per2.getAge()){
System.out.println("两个对象相等");
}
else{
System.out.println("两个对象不相等");
}
}
}
D:\>javac Hello.java
D:\>java Hello
两个对象相等
较为严谨的且专业点的实现方式要利用this代指当前对象并在当前对象中实现比较方法,接收另外一个类的实例化对象,然后对其属性及内存地址进行比较
class Person{
private String name;
private int age;
public Person(String name,int age){
this.setName(name);
this.setAge(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 boolean compare(Person per){
Person p1=this;
Person p2=per;
//直接比较内存地址
if(p1==p2){
return true;
}
if(p1.getName().equals(p2.getName()) && p1.getAge()==p2.getAge()){
return true;
}
return false;
}
}
public class Hello{
public static void main(String args[]){
Person per1=new Person("natural",24);
Person per2=new Person("natural",24);
if(per1.compare(per2)){
System.out.println("两个对象相等");
}
else{
System.out.println("两个对象不相等");
}
}
}
关键字词:this,java