目录
- 基本介绍
super代表父类的引用,用于访问父类的属性、构造器、方法。
一、基本语法
1.访问父类的属性,但不能访问父类的private属性 super.属性名;
2.访问父类的方法,但不能访问父类的private方法 super.方法名(参数列表);
3.访问父类的构造器 super(参数列表);只能放在构造器的第一句并且只能出现一句
二、super给编程带来的好处/细节
1.调用父类构造器的好处(分工明确,父类属性由父类初始化,子类属性由子类初始化)
2.当子类中有和父类中的成员(属性和方法)重名时,为了访问父类的成员,必须通过super。如果没有重名,使用super、this、直接访问是一样的效果
3.super的访问不限于直接父类,如果爷爷类和本类中有同名的成员,也可以使用super去访问爷爷类的成员;如果多个基类(上级类)中都有同名的成员,使用super访问遵循就近原则。
三、super和this的比较
区别点 | this | super | |
---|---|---|---|
访问属性 | 访问本类中的属性,如果本类没有 此属性则从父类中继续查找 | 从父类开始查找属性 | |
调用方法 | 访问本类中的方法,如果本类没有 此方法则从父类中继续查找 | 从父类开始查找方法 | |
调用构造器 | 调用本类构造器,必须放在构造器的首行 | 调用父类构造器,必须放在 子类构造器的首行 | |
特殊 | 表示当前对象 | 子类中访问父类对象 (父类的引用) |
super课堂讲解代码
public class super01 {
public static void main(String[] args) {
B b = new B();//子类对象
//b.sum();
b.Test();
}
}
public class Base { //父类的父类
public int n1 = 999;
public int age = 20;
public void cal(){
System.out.println("Base类的cal方法....");
}
public void eat(){
System.out.println("Base类的eat方法....");
}
}
public class A extends Base{ //父类
//属性
public int n1 = 100;
protected int n2 = 200;
int n3 = 300;
private int n4 = 400;
//构造器
public A(){}
public A(String name){}
public A(String name, int age){}
//方法
public void test100(){}
protected void test200(){}
void test300(){}
private void test400(){}
//细节补充代码
public void cal(){
System.out.println("A类的cal方法....");
}
}
public class B extends A{ //子类
//访问父类的属性,但不能访问父类的private属性 super.属性名;
public void hi(){
System.out.println(super.n1 + " " + super.n2 + " " + super.n3);
}
//访问父类的方法,但不能访问父类的private方法 super.方法名(形参列表);
public void ok(){
super.test100();
super.test200();
super.test300();
}
//访问父类的构造器 super(参数列表); 只能放在构造器第一句,只能出现一句
public B(){
//super();
super("jack",10);
}
//细节补充代码
public int n1 = 888;
public void cal(){
System.out.println("B类的cal方法...");
}
public void sum(){
System.out.println("B类的sum方法....");
//希望调用父类A的cal方法
//因为子类B没有cal方法,因此可以使用下面三种方式
//找cal方法时(cal() 和 this.cal()),顺序如下
// 1.先找本类,如果有,则调用
// 2.如果本类没有,则找父类(如果有,并且可以调用,则调用)
// 3.如果父类没有,则继续找父类的父类,直到找到Object类
// 提示:如果查找方法的过程中找到了,但是不能访问,则报错
// 如果查找方法的过程中没有找到,则提示方法不存在
//cal();
//this.cal();//等价与 cal();
//找cal方法(super.cal())的顺序是直接查找父类,其他规则一样
super.cal();
//访问属性的规则与找方法的规则一致
System.out.println(n1);
System.out.println(this.n1);
System.out.println(super.n1);
}
//编写测试方法Test
public void Test(){
//super的访问不限于直接父类,如果爷爷类和本类中有同名的成员,
//也可以使用super去访问爷爷类的成员;如果多个基类(上级类)中都有同名的成员,
// 使用super访问遵循就近原则。A->B->C,当然也要遵守访问权限的相关规则
System.out.println("super.n1=" + super.n1);
super.cal();
}
}
四、方法重写/覆盖
1.基本介绍
方法重写(覆盖)就是子类有一个方法和父类的某个方法的名称、返回类型、参数一样,那么我们就说子类的这个方法覆盖了父类的方法
2.注意事项和使用细节
①子类方法的形参列表,方法名称要和父类的形参列表、方法名称完全一样
②子类方法的返回类型和父类方法的返回类型要一样,或者是父类返回类型的子类。比如:父类返回类型是Object,子类的返回类型是String
③子类方法不能缩小父类方法的访问权限(可以相等或者扩大)
public→protected→默认→private