Java super关键字详解:访问父类成员、构造方法及与this的区别
本文详细介绍Java中super关键字的核心用途,包括访问父类成员变量、调用父类方法以及触发父类构造器。通过具体代码案例,清晰展示super与this在处理同名变量和方法时的区别,解决继承体系中的访问控制问题。
super关键字的基础概念
在Java的继承体系中,super关键字主要用于引用当前对象的父类实例。它的核心功能包括:
- 访问父类属性:获取被隐藏或同名的父类成员变量值。
- 调用父类方法:在子类覆盖(Override)了父类方法后,显式调用父类原有逻辑。
- 调用父类构造器:在子类构造器中初始化父类部分的状态。
需要注意的是,私有(private)成员无论通过this还是super都无法直接访问。
访问父类属性与方法
当子类继承了父类时,默认可以访问父类非私有的属性和方法。但在存在同名成员时,直接使用名称会优先匹配子类。此时需借助super明确指向父类。
第1步:演示父类定义
首先定义一个包含不同访问修饰符属性和方法的父类,以便后续测试访问权限。
/**
* 演示super关键字的父类
*/
public class SuperFather {
public int n1 = 100;
int n2 = 110; // 包级私有
protected int n3 = 120;
private int n4 = 130; // 私有,子类不可见
public void say() {
System.out.println("我是公开的方法");
}
protected void show() {
System.out.println("我是受保护的方法");
}
private void can() {
System.out.println("我是私有方法");
}
}
第2步:子类中通过super访问父类成员
在子类中,可以直接访问公有和保护成员。若尝试访问私有成员会导致编译错误。以下是正确的使用方式:
/**
* 演示super关键字的子类
*/
public class SuperSon extends SuperFather {
public void test() {
// 访问父类的属性
// 注意:无法通过super访问父类的私有属性n4
System.out.println(super.n1 + super.n2 + super.n3);
// 访问父类的方法
// 同样无法访问父类的私有方法can()
super.say();
super.show();
}
}
父子方法调用的细节
理解super在方法调用中的表现,关键在于区分子类是否重写了该方法。
第3步:子类未重写父类方法
如果子类中没有定义与父类同名且签名相同的方法,直接使用方法名或通过super调用效果基本一致,但语义不同:
sum():先从本类查找,未找到则向上搜索父类。super.sum():跳过本类查找,直接从父类开始搜索。
// 父类中定义
public void sum() {
System.out.println("我是sum功能!");
}
// 子类中调用
sum(); // 正常调用,最终找到父类方法
super.sum(); // 明确指定调用父类方法
第4步:子类重写父类方法(Method Override)
当子类和父类拥有同名方法时,子类对象调用该方法会执行子类的版本(多态)。若需要执行父类的原始逻辑,必须使用super:
// 父类
public void cal() {
System.out.println("我是父类的cal功能 !");
}
// 子类
public class SubClass extends ParentClass {
public void cal() {
System.out.println("我是子类的cal功能!");
}
public void test() {
// 直接调用会执行子类版本
cal();
// 显式调用父类版本
super.cal();
}
}
属性的遮蔽(Shadowing)规则与此相同:若子类定义了同名属性,默认操作的是子类属性,需用super.variableName访问父类属性。
super与this的关键区别
this代表当前对象本身,而super代表当前对象的父类部分。两者在使用场景上有显著差异:
- 变量访问:
this.name指向子类变量,super.name指向父类变量。 - 方法调用:
this.print()可能触发动态绑定(多态),super.print()强制调用父类静态绑定的方法。 - 构造器:
this()调用同类其他构造器,super()调用父类构造器。
第5步:代码综合对比演示
以下示例展示了test方法输出本地参数、子类字段和父类字段的差异,以及test2方法输出不同层级打印结果的差异。
// 父类
public class Person {
public String name = "小卤蛋";
public void print(){
System.out.println("Person");
}
}
// 子类
public class Student extends Person{
private String name = "鲁班七号";
public void test(String name){
// 输出传入的参数
System.out.println(name); // 鲁班七号
// 输出子类自己的属性
System.out.println(this.name); // 鲁班七号
// 输出父类的属性
System.out.println(super.name); // 小卤蛋
}
public void print(){
System.out.println("Student");
}
public void test2(){
print(); // 实际调用子类print,输出: Student
this.print(); // 显式调用子类print,输出: Student
super.print(); // 强制调用父类print,输出: Person
}
}
// 主方法测试
public static void main(String[] args) {
Student student = new Student();
student.test("鲁班七号");
student.test2();
}
总结
掌握super关键字是理解Java面向对象继承机制的重要一环。它能帮助你在代码扩展和维护过程中,灵活地复用父类逻辑并处理命名冲突。简单来说:想访问“爸爸”的东西用super,想操作“自己”的东西用this。以上就是Java super关键字的使用详解的详细内容,更多关于Java super关键字使用方法及继承机制的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













