this和super的作用介绍
this代表的是本类对象,一般用来调用方法外部的本类实例变量和方法。
super代表的是当前类的父类引用,使用super,可以调用被子类重写的方法和变量。
给出一段使用this 和 super 的代码:
public class Test {
public static void main(String[] args) {
//创建无参数的B对象
B b = new B();
//创建带参的B类对象
B b2 = new B("BBB");
System.out.println(b2.getName()); //B类的getName()是隐式存在的。
}
}
class A{
private String name; //私有成员变量
public A() {
System.out.println("A类默认构造器");
}
public A(String name) {
// name.name; 不使用this,这时两个name都是指向形参 String name ,因为这两个name的作用域仅限于此方法
this.name = name; //使用this,则代表当前类的对象来访问,所以会指向实例变量name
}
protected void infoA() {
System.out.println("A类~~~~info()");
}
public String getName() {
return name;
}
}
class B extends A{
public B() {
System.out.println("B类默认构造器");
}
public B(String name) {
super(name);
}
//调用父类的方法,使用super
public void infoB() {
super.infoA();
}
/* @Override
public String getName() {
return super.getName();
}*/
}
//输出结果
//A类默认构造器
//B类默认构造器
//BBB
上面代码可以看出,当形参名与实例变量名重名时,使用this可以改变作用域,所以this.name会指向当前类的同名实例变量。
使用super则可以在子类中调用父类方法和实例,但父类的方法和字段默认对子类隐藏。例如getName()方法,在子类B的代码中没有直接显示,但是却可以调用该方法。如果对方法进行重写,要调用原来的方法就使用super。
注意点:如果子类对继承的方法或者字段进行重写和修改时,原来的父类方法和字段依然会存在,只是隐藏了,所以要调用就需要使用super关键字。
this() 和 super() :
this() 表示调用当前类的构造器,而super()则表示调用父类的构造器。根据是否传入参数和参数数量来调用指定的构造器。
当一个类有多个构造器,且参数数量不同,在参数多的构造器中就可以调用另外的构造器,简化赋值过程。
this() 和 super() 使用规则:
this() 和 super()只能放在构造器中第一行语句中,在第一行调用this() 或者super()之后 ,如果继续调用则会编译错误。
构造器的特点:
在构造器中的第一行总是会隐式的传入一个super(),也可以显式调用 ,所以父类的构造器总是优先于子类构造器。
this 和 super的注意点:
this 与 super 是不能调用静态方法和静态字段的,也不能在静态方法中使用this 和 super。例如主方法中是无法使用this和super的。
下面代码演示:
public class Test01 {
public static void main(String[] args) {
Abc a = new Abc();
Bcd b = new Bcd();
a.test01();
b.testThis();
}
}
class Abc{
public int abc = 100;
//静态方法使用this
public static void test01() {
//System.out.println(this.abc);
}
//实例方法中使用this
public void testThis() {
int abc = 300;
System.out.println("获取abc值:" + abc);
System.out.println("使用this来获取abc值:" + this.abc);
}
}
class Bcd extends Abc{
//静态方法中使用super
public static void test() {
//System.out.println(super.abc);
}
//实例方法中使用super调用父类abc值
public void testSuper() {
System.out.println(super.abc);
super.test01(); //调用父类的静态方法
}
//子类中重写了父类的类方法test01(),静态方法无法被重写。
// public void test01() { }
}
在上面代码中,子类尝试对父类的同名方法test01()进行重写,会出现提示——静态方法无法重写成实例方法。因为静态方法可虽然可以被继承,但是只能隐藏在子类中,子类也无法对其覆写。而且静态方法是属于类本身的,不属于实例方法,所以子类无法对其重写。
如果子类也定义一个同名的静态方法,例如 public static void test01(){},这个方法是属于子类本身的,和父类的同名方法毫无关联,这两个没有一毛钱关系。
静态方法是属于类本身的,虽然对象也可以调用静态方法,但静态方法违背了子类重写父类规则。所以使用静态方法从本质上来说是无法实现多态的。