引入
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关键字。