this和super

一、this

  1.指代当前类的对象

        每个对象都会持有自己的一个this,是一个引用类型变量,存放是对象自身在内存中的地址值。或者说,this是一个指向对象自身的指针。

     (1)在构造方法里用this

class Date {
    int year;
    int month;
    int day;

    //构造方法
    public Date(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
    }
 
    public void print() {      
    }
}

          目的:区分方法传过来的参数year 和 对象的成员变量this.year。

     (2)成员方法的形参中,默认第一个参数是this

          此this的作用是:指出在哪个对象上调用此方法。其也称为方法的隐式参数,存放于虚拟机栈的局部变量表。

     (3)把对象自身作为参数传递给别的方法

public class Test {

    public void m1(){
        m2(this);    //把this传给另一个方法
    }

    public void m2(Test t){
        System.out.println(t);
    }
}

   (4)调用成员方法或成员变量,隐式加this

public class IdCard {

    //成员变量
    private String city;

    //用this访问本对象的成员变量(this可去掉)
    public void print() {
        System.out.println(this.city);
    }

    //用this访问本对象的成员方法(this可去掉)
    public void print1() {
        this.print();
    }
}

     (5)类名.this

        和上面一样,都是指代当前类的对象,但一般应用在含有内部类的场景上。因为只用this,读者无法区分外部类和内部类(编译器可以区分, 不用类名.this也不会报错),所以采用类名.this区分。

        根据用法分两种情况讨论:

  1. 一般的使用情况,是内部类直接访问外部类的成员变量或方法,成员变量或方法不重名。即使不加“类名.this”区分,读者也不会觉得有歧义性;
class Outer {
  String name;
        
  class Inner {  
      void printInner() {
        System.out.println(name);
        //读者自然想到name是外部类的name, 但实际上name等同于Outer.this.name
      }  
  }  
}

     2.内部类和外部类的成员变量或方法重名,读者理解起来稍有歧义性,用“类名.this”区分更好。

class Outer {
  String name;   //外部类和内部类都有name成员变量
    
  void printOuter() {
    System.out.println(Outer.this.name);//Outer.this.name也等同于this.name, this可被自动识别是Outer对象; 甚至连this也可去掉,直接用name;
  }  
    
  class Inner {
      String name;//外部类和内部类都有name成员变量
      
      void printInner() {
        System.out.println(Inner.this.name);//Inner.this.name也等同于this.name, this可被自动识别是Inner对象; 甚至连this也可去掉,直接用name;
      }  
  }  
}

          注:本小节的例子用的是普通内部类,用匿名内部类同理!

2.指代本类构造方法

        适用场景:构造方法调用另一个构造方法。

   (1)有参构造方法调用无参构造方法时,用this();

        注意:this()要写在方法第一行,不然报错。

public class Test {

    //构造方法1
    Test() {
        System.out.println("hello");
    }

    //构造方法2
    Test(int count) {
        this();
        System.out.println(count);
    }

}

   (2)无参构造方法调用有参构造方法,用this(参数);

        注意:this(参数)要写在方法第一行,不然报错。

public class Test {

    //构造方法1
    Test() {
        this(10);
        System.out.println("hello");
    }

    //构造方法2
    Test(int count) {
        System.out.println(count);
    }
}

二、super

   1.指代父类的对象

class Father {
    String color;
    
    public void printColor() {
            
    }
}

class Son extends Father {
    String color;

    public void printColor() {
        System.out.println(this.color);  //使用当前类的对象的成员变量
        System.out.println(super.color); //使用父类的对象的成员变量
        super.printColor();              //调用父类的对象的成员方法
    }
}

   2.指代父类的构造方法

        适用场景:当前类的构造方法(显示/隐式)调用父类的构造方法。

class Father {
    String color;
    
    public Father(String color) {
        this.color = color;
    }
}

class Son extends Father {
    String color;

    public Son(String color) {
        super(color);      //显示调用父类的有参构造方法
        this.color = color;
    }    
}

        此处子类构造方法显示调用父类构造方法,把它改成显示调用父类的无参构造方法,再来品品里面的知识点:

  public Son(String color) {
        super();           /**此处显示调用父类的无参构造方法。
                            写不写super()都无所谓; 因为其调用是隐式的; 不管写不写super(), new对象时,JVM会先调用父类的构造方法,再调用子类构造方法。
                            但需要父类的无参构造方法不被去掉,不然会报错。 
                            因为有个原则:如果父类已经有一个构造方法, 无参的构造方法会失效。                                                     
                            (则:要么,父类不写任何的构造方法,有个隐式的无参的构造方法;要么,父类只定义个无参的构造方法;要么父类同时定义无参构造方法和有参构造方法))。**/
        this.color = color;
    }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值