乐趣区

关于java:面试官this和super有什么区别this能调用到父类吗

本文已收录《Java 常见面试题》:https://gitee.com/mydb/interview

this 和 super 都是 Java 中常见的关键字,尽管二者在很多状况下都能够被省略,但它们在 Java 中所起的作用是不可磨灭的。它们都是用来起指代作用的,每个类在实例化的时候之所以能调用到 Object 类(Object 类是所有类的父类),全是二者的“功绩”。

1.super 关键字

super 是用来拜访父类实例属性和办法的。

1.1 super 办法应用

每个实例类如果没有显示的指定构造方法,那么它会生成一个暗藏的无参构造方法。对于 super() 办法也是相似,如果没有显示指定 super() 办法,那么子类会生成一个暗藏的 super() 办法,用来调用父类的无参构造方法,这就是咱们开篇所说的“每个类在实例化的时候之所以能调用到 Object 类,就是默认 super 办法起作用了”,接下来咱们通过实例来验证一下这个说法。

PS:所谓的“显示”,是指在程序中被动的调用,也就是在程序中增加相应的执行代码。

public class SuperExample {
    // 测试方法
    public static void main(String[] args) {Son son = new Son();
    }
}

/**
 * 父类
 */
class Father {public Father() {System.out.println("执行父类的构造方法");
    }
}

/**
 * 子类
 */
class Son extends Father {}

在以上代码中,子类 Son 并没有显示指定 super() 办法,咱们运行以上程序,执行的后果如下:

从上述的打印后果能够看出,子类 Son 在没有显示指定 super() 办法的状况下,居然调用了父类的无参构造方法,这样从侧面验证了,如果子类没有显示指定 super() 办法,那么它也会生成一个暗藏的 super() 办法。这一点咱们也能够从此类生成的字节码文件中失去证实,如下图所示:

super 办法注意事项

如果显示应用 super() 办法,那么 super() 办法必须放在构造方法的首行,否则编译器会报错,如下代码所示:

如上图看到的那样,如果 super() 办法没有放在首行,那么编译器就会报错:提醒 super() 办法必须放到构造方法的首行。
为什么要把 super() 办法放在首行呢?
这是因为,只有将 super() 办法放在首行,那么在实例化子类时能力确保父类曾经被先初始化了。

1.2 super 属性应用

应用 super 还能够调用父类的属性,比方以下代码能够通过子类 Son 调用父类中的 age 属性,实现代码如下:

public class SuperExample {
    // 测试方法
    public static void main(String[] args) {Son son = new Son();
    }
}

/**
 * 父类
 */
class Father {
    // 定义一个 age 属性
    public int age = 30;

    public Father() {super();
        System.out.println("执行父类的构造方法");
    }
}

/**
 * 子类
 */
class Son extends Father {public Son() {System.out.println("父类 age:" + super.age);
    }
}

以上程序的执行后果如下图所示,在子类中胜利地获取到了父类中的 age 属性:

2.this 关键字

this 是用来拜访本类实例属性和办法的,它会先从本类中找,如果本类中找不到则在父类中找。

2.1 this 属性应用

this 最常见的用法是用来赋值本类属性的,比方常见的 setter 办法,如下代码所示:

上述代码中 this.name 示意 Person 类的 name 属性, 此处的 this 关键字不能省略 ,如果省略就相当于给以后的局部变量 name 赋值 name,本人给本人赋值了。咱们能够尝试一下,将 this 关键字勾销掉,实现代码如下:

class Person {
    private String name;
    public void setName(String name) {this.name = name;}
    public String getName() {return name;}
}
public class ThisExample {public static void main(String[] args) {Person p = new Person();
        p.setName("磊哥");
        System.out.println(p.getName());
    }
}

以上程序的执行后果如下图所示:

从上述后果能够看出,将 this 关键字去掉之后,赋值失败,Person 对象中的 name 属性就为 null 了。

2.2 this 办法应用

咱们能够应用 this() 办法来调用本类中的构造方法,具体实现代码如下:

public class ThisExample {
    // 测试方法
    public static void main(String[] args) {Son p = new Son("Java");
    }
}

/**
 * 父类
 */
class Father {public Father() {System.out.println("执行父类的构造方法");
    }
}

/**
 * 子类
 */
class Son extends Father {public Son() {System.out.println("子类中的无参构造方法");
    }
    public Son(String name) {
        // 应用 this 调用本类中无参的构造方法
        this();
        System.out.println("子类有参构造方法,name:" + name);
    }
}

以上程序的执行后果如下图所示:

从上述后果中能够看出,通过 this() 办法胜利调用到了本类中的无参构造方法。

留神:this() 办法和 super() 办法的应用规定一样,如果显示的调用,只能放在办法的首行。

2.3 this 拜访父类办法

接下来,咱们尝试应用 this 拜访父类办法,具体实现代码如下:

public class ThisExample {public static void main(String[] args) {Son son = new Son();
        son.sm();}
}

/**
 * 父类
 */
class Father {public void fm() {System.out.println("调用了父类中的 fm() 办法");
    }
}

/**
 * 子类
 */
class Son extends Father {public void sm() {System.out.println("调用子类的 sm() 办法拜访父类办法");
        // 调用父类中的办法
        this.fm();}
}

以上程序的执行后果如下:

从上述后果能够看出,应用 this 是能够拜访到父类中的办法的,this 会先从本类中找,如果找不到则会去父类中找。

3.this 和 super 的区别

1. 指代的对象不同

super 指代的是父类,是用来拜访父类的;而 this 指代的是以后类。

2. 查找范畴不同

super 只能查找父类,而 this 会先从本类中找,如果找不到则会去父类中找。

3. 本类属性赋值不同

this 能够用来为本类的实例属性赋值,而 super 则不能实现此性能。

4.this 可用于 synchronized

因为 this 示意以后对象,所以 this 可用于 synchronized(this){….} 加锁,而 super 则不能实现此性能。

总结

this 和 super 都是 Java 中的关键字,都起指代作用,当显示应用它们时,都须要将它们放在办法的首行(否则编译器会报错)。this 示意以后对象,super 用来指代父类对象,它们有四点不同:指代对象、查找拜访、本类属性赋值和 synchronized 的应用不同。

是非审之于己,毁誉听之于人,得失安之于数。
公众号:Java 面试真题解析

退出移动版