Java this () and super () to use

 

Original Address: http: //www.cnblogs.com/hasse/p/5023392.html

this three main functions:

this property call, call the method, use this represents the current object.

this

this is an object itself, representative of the object itself, it can be understood as: a pointer to the object itself.

this usage in java can be divided into three kinds:

1. Ordinary direct reference

This would not have talked about, this is the equivalent of pointing to the current object itself.

2. shaped participating members name the same name, with this distinguished:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

class Person {

    private int age = 10;

    public Person(){

    System.out.println("初始化年龄:"+age);

}

    public int GetAge(int age){

        this.age = age;

        return this.age;

    }

}

 

public class test1 {

    public static void main(String[] args) {

        Person Harry = new Person();

        System.out.println("Harry's age is "+Harry.GetAge(12));

    }

}       

operation result:

Initialization Age: 10
Harry's Age IS 12

It can be seen here is the age parameter GetAge member methods, this.age variable Person is a member of the class.

3. References inside the constructor

Speak together on this and super, see below.

super

super can be understood as pointing to his own super (parent) of a class object pointer, and this superclass refers to the nearest one parent class.

There are also three super usage:

1. Ordinary direct reference

And this is similar, super equivalent refers to the current object's parent class, so that you can use super.xxx to refer to members of the parent class.

2. subclass member variables or methods of the parent class member variable or method with the same name

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

class Country {

    String name;

    void value() {

       name = "China";

    }

}

  

class City extends Country {

    String name;

    void value() {

    name = "Shanghai";

    super.value();      //调用父类的方法

    System.out.println(name);

    System.out.println(super.name);

    }

  

    public static void main(String[] args) {

       City c=new City();

       c.value();

       }

}

operation result:

Shanghai
China

We can see, both the parent class method called here, also called variable parent class. If the parent class method calls the value (), only the variable name to call the parent class, then the parent class name is the default value null.

3. References inside the constructor

super (parameters): one call parent class constructor (the constructor should be the first statement).

this (parameters): call another form of this class constructor (the constructor must be the first statement).

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

class Person { 

    public static void prt(String s) { 

       System.out.println(s); 

    

   

    Person() { 

       prt("父类·无参数构造方法: "+"A Person."); 

    }//构造方法(1) 

    

    Person(String name) { 

       prt("父类·含一个参数的构造方法: "+"A person's name is " + name); 

    }//构造方法(2) 

    

public class Chinese extends Person { 

    Chinese() { 

       super(); // 调用父类构造方法(1) 

       prt("子类·调用父类”无参数构造方法“: "+"A chinese coder."); 

    

    

    Chinese(String name) { 

       super(name);// 调用父类具有相同形参的构造方法(2) 

       prt("子类·调用父类”含一个参数的构造方法“: "+"his name is " + name); 

    

    

    Chinese(String name, int age) { 

       this(name);// 调用具有相同形参的构造方法(3) 

       prt("子类:调用子类具有相同形参的构造方法:his age is " + age); 

    

    

    public static void main(String[] args) { 

       Chinese cn = new Chinese(); 

       cn = new Chinese("codersai"); 

       cn = new Chinese("codersai"18); 

    

}

operation result:

父类·无参数构造方法: A Person.
子类·调用父类”无参数构造方法“: A chinese coder.
父类·含一个参数的构造方法: A person's name is codersai
子类·调用父类”含一个参数的构造方法“: his name is codersai
父类·含一个参数的构造方法: A person's name is codersai
子类·调用父类”含一个参数的构造方法“: his name is codersai
子类:调用子类具有相同形参的构造方法:his age is 18

从本例可以看到,可以用super和this分别调用父类的构造方法和本类中其他形式的构造方法。

例子中Chinese类第三种构造方法调用的是本类中第二种构造方法,而第二种构造方法是调用父类的,因此也要先调用父类的构造方法,再调用本类中第二种,最后是重写第三种构造方法。

 

super和this的异同:

  • super(参数):调用基类中的某一个构造函数(应该为构造函数中的第一条语句) 
  • this(参数):调用本类中另一种形成的构造函数(应该为构造函数中的第一条语句)
  • super: 它引用当前对象的直接父类中的成员(用来访问直接父类中被隐藏的父类中成员数据或函数,基类与派生类中有相同成员定义时如:super.变量名    super.成员函数据名(实参)
  • this:它代表当前对象名(在程序中易产生二义性之处,应使用this来指明当前对象;如果函数的形参与类中的成员数据同名,这时需用this来指明成员变量名)
  • 调用super()必须写在子类构造方法的第一行,否则编译不通过。每个子类构造方法的第一条语句,都是隐含地调用super(),如果父类没有这种形式的构造函数,那么在编译的时候就会报错。
  • super()和this()类似,区别是,super()从子类中调用父类的构造方法,this()在同一类内调用其它方法。
  • super()和this()均需放在构造方法内第一行。
  • 尽管可以用this调用一个构造器,但却不能调用两个。
  • this和super不能同时出现在一个构造函数里面,因为this必然会调用其它的构造函数,其它的构造函数必然也会有super语句的存在,所以在同一个构造函数里面有相同的语句,就失去了语句的意义,编译器也不会通过。
  • this()和super()都指的是对象,所以,均不可以在static环境中使用。包括:static变量,static方法,static语句块。
  • 从本质上讲,this是一个指向本对象的指针, 然而super是一个Java关键字。

 

1.this关键字

 

对于上述需要注意的地方:

1.不是重载即在构造器中调用构造器可以直接调用其方法,无需this。在需要明确的地方使用即可

 

2.疑惑点

 

this关键字对于将当前对象传递给其他的方法也很有用,这一点自己现在也不是很熟练

2.在构造器中调用构造器

 

[java] view plain copy

  1. package test;  
  2.   
  3. public class Test {  
  4.       int petalCount = 0;  
  5.       String s = "initial value";  
  6.       Test(int petals) {  
  7.         petalCount = petals;  
  8.         System.out.println("Constructor w/ int arg only, petalCount= "  
  9.           + petalCount);  
  10.       }  
  11.       Test(String ss) {  
  12.           s = ss;  
  13.         System.out.println("Constructor w/ String arg only, s = " + s);  
  14. //      s=ss;  要是将上面的语句放到下面,这输出s的值就是initial  value;  
  15.       }  
  16.       Test(String s, int petals) {  
  17. //      this(petals);// Can't call two!  
  18.         this(s);   
  19. //      上面语句是调用另外一个构造器,下面是将由于参数s的名称和数据成员s的名字相同,所以会产生歧义  
  20. //      因此使用this.s来代表数据成员就能解决这个问题  
  21.         this.s = s; // Another use of "this"  
  22.         System.out.println("String & int args");  
  23.       }  
  24.       Test() {  
  25.         this("hi", 47);  
  26.         System.out.println("default constructor (no args)");  
  27.       }  
  28.       void printPetalCount() {  
  29.     //! this(11); // Not inside non-constructor!  
  30.         System.out.println("petalCount = " + petalCount + " s = "+ s);  
  31.       }  
  32.       public static void main(String[] args) {  
  33.         Test x = new Test();  
  34.         x.printPetalCount();  
  35.       }  
  36.     }   

 

例子:

 

[java] view plain copy

  1. package test;  
  2.   
  3. public class Test {  
  4.   
  5.     private int i=0;  
  6.   
  7.     //第一个构造器:有一个int型形参  
  8.   
  9.     Test(int i){  
  10.           
  11.        System.out.println("i:"+this.i);  
  12.          
  13.        this.i=i+1;//此时this表示引用成员变量i,而非函数参数i  
  14.          
  15.        //下面的i表示形参i,this.i表示数据成员  
  16.        System.out.println("Int constructor i——this.i:  "+i+"  ——  "+this.i);  
  17.          
  18.        System.out.println("i:"+this.i);  
  19.   
  20.        System.out.println("  i-1:  "+(i-1)+"  this.i+1:  "+(this.i+1));  
  21.   
  22.        //从两个输出结果充分证明了i和this.i是不一样的!  
  23.   
  24.     }  
  25.   
  26.     //  第二个构造器:有一个String型形参  
  27.   
  28.     Test(String s){  
  29.           
  30. //      重新调用新的构造器之后,数据成员的值不再受到上一个的影响  
  31. //      难道是因为每个构造器都有自己独立内存空间吗?  
  32.        System.out.println("2i:"+this.i);  
  33.          
  34.        System.out.println("String constructor:  "+s);  
  35.   
  36.     }  
  37.   
  38.     //  第三个构造器:有一个int型形参和一个String型形参  
  39.   
  40.     Test(int i,String s){  
  41.   
  42.        this(s);//this调用第二个构造器  
  43.   
  44.        /*this(i);*/  
  45.   
  46.        /*此处不能用,因为其他任何方法都不能调用构造器,只有构造方法能调用他。 
  47.  
  48.        但是必须注意:就算是构造方法调用构造器,也必须为于其第一行,构造方法也只能调 
  49.  
  50.        用一个且仅一次构造器! 
  51.        http://blog.sina.com.cn/s/blog_8612e75d0100ze1m.html 
  52.        */  
  53.          
  54.        System.out.println("3i:"+this.i);  
  55.          
  56.        this.i=i++;//this以引用该类的成员变量  
  57.   
  58.        System.out.println("Int constructor:  "+i+"\n"+"String constructor:  "+s);  
  59.   
  60.     }  
  61.   
  62. /*    Test(int i ,String s,double a){ 
  63.          
  64.         this(i); 
  65.          System.out.println("5i:"+this.i); 
  66.     }*/  
  67.       
  68.     public Test increment(){  
  69.   
  70.         System.out.println("4i:"+this.i);  
  71.         this.i++;  
  72.        return this;//返回的是当前的对象,该对象属于(Test)  
  73.   
  74.     }  
  75.   
  76.     public static void main(String[] args){  
  77.   
  78.        Test tt0=new Test(10);  
  79.   
  80.        Test tt1=new Test("ok");  
  81.   
  82.        Test tt2=new Test(20,"ok again!");  
  83.          
  84.       /* Test tt3=new Test(15, "okhushid", 0.12345);*/  
  85.   
  86.      //由于increment()通过this关键字返回了当前对象的引用,所以很容易在一条语句里面对同一个对象执行多次操作  
  87.        System.out.println(tt0.increment().increment().increment().i);  
  88. //       输出的是this.i,就相当于输出其数据成员  
  89.        System.out.println(tt0.increment().increment().increment());  
  90. //       输出的是test.Test@2b0a141e,这是什么?这是java中的内存地址吗?  
  91.          
  92.          
  93.        //http://www.cnblogs.com/java-class/archive/2012/12/19/2825463.html  
  94.   
  95.     }  
  96.   
  97. }  

 

关于this()与super()共用的问题:

 

[java] view plain copy

  1. package test;  
  2.   
  3. class TestA {  
  4.       public TestA() {  
  5.          System.out.println("A");  
  6.       }  
  7.     }  
  8.        
  9.     class TestB extends TestA {  
  10.       public TestB(int i) {  
  11.        super();  

[java] view plain copy

  1.          // this();  
  2.        
  3.   }  
  4.    
  5.   public TestB() {  
  6.       this(3);  
  7.   System.out.println("B");  
  8.   }  
  9. }  
  10.    
  11. public class Test {  
  12.   public static void main(String[] ars) {  
  13.      new TestB(1);  
  14.      new TestB();  
  15.   }  
  16. }  


super()和this ()不能共存,否则编译时会报异常。
Constructor call must be the first statement in a constructor
换句话说就是super()和this ()都必须在构造方法的第一行。
this(有参数/无参数) 用于调用本类相应的构造函数
super(有参数/无参数) 用于调用父类相应的构造函数
而且在构造函数中,调用必须写在构造函数定义的第一行,不能在构造函数的后面使用。
一个构造函数定义中不能同时包括this调用和super调用,如果想同时包括的话,可以在一每构造器中使用一个。

 

 

 补充:

   用类名定义一个变量的时候,定义的应该只是一个引用,外面可以通过这个引用来访问这个类里面的属性和方法,那们类里面是够也应该有一个引用来访问自己的属性和方法纳?JAVA提供了一个很好的东西,就是 this 对象,它可以在类里面来引用这个类的属性和方法。

 

[java] view plain copy

  1. public class ThisDemo {    
  2.     String name="Mick";  
  3.     public void print(String name){  
  4.         System.out.println("类中的属性 name="+this.name);  
  5.         System.out.println("局部传参的属性="+name);  
  6.     }     
  7.     public static void main(String[] args) {  
  8.         ThisDemo tt=new ThisDemo();  
  9.         tt.print("Orson");  
  10.     }  
  11. }  


 

自我问题:

http://bbs.csdn.net/topics/391819324?page=1#post-400326846

第一个问题:每次重新调用一个新的构造器之后,this.i的数据都会恢复到原来了0;上一个构造器的this.i的结果没有保存,难道在java中每个构造器都有自己的内存空间地址吗?


第二个问题:   System.out.println(tt0.increment().increment().increment());
//       输出的是test.Test@2b0a141e,这是什么?这是java中的内存地址吗?

 

第一个问题:
构造器(构造函数,Constructor)是一种特殊的函数,它是用来初始化一个“刚刚建立”的对象的方法。不同的构造器重载用于以不同的方式初始化这个对象(其中的逻辑是由编程人员自由控制的)。对于同一个类内的构造器,对于每个对象只能被调用一次,且是由new方法发起调用,可以使用super(调用父类的构造方法)和this(调用本类的构造方法)在不同构造器方法之间跳转,但是每个构造方法最多被调用一遍,同一个类内的构造方法最多有一个是实质上执行的(如果递归,编译器会报错)。this是对当前对象的引用,每次构造器调用时都是作用于一个全新的对象,故每次调用时其类中数据成员的值(那个i是成员变量,在每个对象中有独立的存储空间)一定是未初始化的默认值。

 

static:只有静态成员变量才是整个类共用的。对于非静态成员变量每个对象保存一个独立的值(当然占用的就是对象的空间)。



第二个问题:
当没有重写toString方法时,默认会使用Object类提供的toString方法,其规则是:类全名@类对象的hashcode方法返回值。当没有重写hashCode方法时,默认使用Object类的hashCode方法,它是java对一个对象的标识号,可能由不同机制生成,不一定是内存地址,但是可能与之相关(通常实现采用的是将地址转换为int值的方法)。

 

 

要搞清楚成员变量和局部变量

Test(int i){ },这个构造器中形参 i 是一个局部变量,作用域是这个构造器的大括号,意思是 声明一个局部变量i,是这个构造器的形参,其值为传入的实参的值,在这个构造器中的i 是指的这个局部变量。

在类中也声明了一个成员变量i,在构造器中也能调用这个变量,但是名字都一样,为了区分应this.i表示这个成员变量,这里的this是指本类的属性

发布了6 篇原创文章 · 获赞 3 · 访问量 802

Guess you like

Origin blog.csdn.net/SmileLucki/article/details/104195225