Java学习——super 与 this 关键字

1,389 阅读4分钟

引入

一、this 的三大作用

1、普通的直接引用:

2、形参与成员名字重名,用this来区分:

3、引用构造函数

二、super 的三种用法

1、普通的直接引用

2、子类中的成员变量或方法与父类中的成员变量或方法同名

3、引用构造函数

三、注意事项

引入

super关键字:我们可以通过super关键字来实现对父类成员的访问,用来引用当前对象的父类。

this关键字:指向自己的引用。

class Animal {
  void eat() {
    System.out.println("animal : eat");
  }
}
 
class Dog extends Animal {
  void eat() {
    System.out.println("dog : eat");
  }
  void eatTest() {
    this.eat();   // this 调用自己的方法
    super.eat();  // super 调用父类方法
  }
}
 
public class Test {
  public static void main(String[] args) {
    Animal a = new Animal();
    a.eat();
    Dog d = new Dog();
    d.eatTest();
  }
}

输出结果为:

animal : eat
dog : eat
animal : eat

一、this 的三大作用

1、普通的直接引用:

this相当指向当前对象本身。

2、形参与成员名字重名,用this来区分:

class Person {
    private int age = 10;
    public Person(){
    System.out.println("初始化年龄:"+age);
}
    public int GetAge(int age){
        this.age = age; //this.age指的是Person类里定义的成员变量age,=后面的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));
    }
}       

运行结果:

初始化年龄:10
Harry's age is 12

3、引用构造函数

这个和super放在一起讲,见下面。

二、super 的三种用法

super可以理解为是指向自己超(父)类对象的一个指针,而这个超类指的是离自己最近的一个父类。

1、普通的直接引用

与this类似,super相当于是指向当前对象的父类,这样就可以用super.xxx来引用父类的成员。

2、子类中的成员变量或方法与父类中的成员变量或方法同名

class Country {
    String name;
    void value() {
       name = "China";
    }
}
  
class City extends Country {
    String name;
    void value() {
    name = "Shanghai";
    super.value();      //调用父类的方法,将父类的name由默认值null变为china。
    System.out.println(name);
    System.out.println(super.name);
    }
  
    public static void main(String[] args) {
       City c=new City();
       c.value();
       }
}

运行结果:

Shanghai
China

可以看到,这里既调用了父类的方法,也调用了父类的变量。

一共有两个name变量,一个是父类的,一个是子类的。

若不调用父类方法value(),只调用父类变量name的话,则父类name值为默认值null。

super.value调用了父类的方法,只改变了父类的name,与子类的name无关,所以子类输出的仍是shanghai。

调用完value()方法后内存中父类的name值改变了(此改变保留,不是暂时性的)

3、引用构造函数

super(参数):调用父类中的某一个构造函数

this(参数):调用本类中另一种形式的构造函数

下面程序按【】中数字顺序获得结果

class Person { 
    public static void prt(String s) { 
       System.out.println(s); 
    } 
   
    Person() { 
       prt("父类·无参数构造方法: "+"A Person."); //prt:System.out.println() 
       【3】
    }//构造方法(1) 
    
    Person(String name) { 
       prt("父类·含一个参数的构造方法: "+"A person's name is " + name); 【7】【13】
    }//构造方法(2) 
} 
    
public class Chinese extends Person { 
    Chinese() { 
       super(); // 调用父类构造方法(1) 【2】
       prt("子类·调用父类”无参数构造方法“: "+"A chinese coder."); 【4】
    } 
    
    Chinese(String name) { 【11】
       super(name);// 调用父类具有相同形参的构造方法(2) 【6】【12】
       prt("子类·调用父类”含一个参数的构造方法“: "+"his name is " + name); 【8】【14】
    } 
    
    Chinese(String name, int age) { 
       this(name);// 调用具有相同形参的构造方法相当于调用的是Chinese(String name)
       【10】
       prt("子类:调用子类具有相同形参的构造方法:his age is " + age); 【15】
    } 
    
    public static void main(String[] args) { 
       Chinese cn = new Chinese(); // 【1】
       cn = new Chinese("codersai"); 【5】
       cn = new Chinese("codersai", 18); 【9】
    } 
}

运行结果:(括号中数字与程序中步骤编号相对应)

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

三、注意事项

调用super()必须写在子类构造方法的第一行,否则编译不通过。每个子类构造方法的第一条语句,都是隐含地调用super(),如果父类没有这种形式的构造函数,那么在编译的时候就会报错。

super()和this()均需放在构造方法内第一行。

尽管可以用this调用一个构造器,但却不能调用两个。

this和super不能同时出现在一个构造函数里面,因为this必然会调用其它的构造函数,其它的构造函数必然也会有super语句的存在,所以在同一个构造函数里面有相同的语句,就失去了语句的意义,编译器也不会通过。

this()和super()都指的是对象,所以,均不可以在static环境中使用。包括:static变量,static方法,static语句块。

从本质上讲,this是一个指向本对象的指针, 然而super是一个Java关键字。