Java笔记整理 —— super关键字、方法重写/覆盖

本文详细介绍了Java中的super关键字及其用途,包括访问父类的属性、方法和构造器。同时,文章探讨了方法重写(override)的概念,强调了重写规则,如返回类型、访问权限和签名的匹配。文中通过实例展示了如何在子类中调用父类的方法,并解释了super关键字在多层继承中的作用。此外,还提到了子类覆盖父类方法时的注意事项,如访问权限的限制和就近原则。
摘要由CSDN通过智能技术生成

super关键字

基本介绍

super代表父类的引用,用于访问父类的属性、方法、构造器。

基本语法

1. 访问父类的属性,但不能访问父类的private属性:super.属性名;

2. 访问父类的方法,但不能访问父类的private方法:super.方法名(参数列表);

3. 访问父类的构造器(前面介绍过):super(参数列表); 只能放在构造器的第一句,只能出现一句

细节/好处

1. super调用父类构造器,可以使分工明确。父类属性由父类初始化,子类的属性由子类初始化。 

2. 当子类中由和父类中的成员(属性和方法)重名时,为了访问父类的成员,必须通过super如果没有重名,使用super、this、直接访问是一样的效果(只不过this和直接访问是从本类开始找,super是从父类开始找)。 调用类的属性的规则在上面已经说明过了,调用类的方法的规则与其相同,只不过把属性换成了方法。

子类确实可以写一个与父类完全相同的方法,虽然左边会有隐患提示,但是编译没有问题。

  下面对于子类调用父类的方法举一个例子(属性因为很简单就不举例了)

  定义一个父类Person:

public class Person {  //有四个不同修饰符的方法
    public void showName1(){
        System.out.println("调用Person的public方法");
    }
    void showName2(){
        System.out.println("调用Person的无修饰符方法");
    }
    protected void showName3(){
        System.out.println("调用Person的protected方法");
    }
    private void showName4(){
        System.out.println("调用Person的private方法");
    }
}

  定义一个子类Student,先测试在main方法中调用方法(必须用声明的变量调用):

public class Student extends Person{
    public static void main(String[] args) {
        Student student = new Student();
        student.showName1();   //成功调用
        student.showName2();   //成功调用  
        student.showName3();   //成功调用
        student.showName4();   //报错,不能调用父类的private方法
    }
}

    然后在子类的方法中继续测试,由于 this 和 super 都不能在主方法中调用,因此声明一个test方法,在该方法中测试this和super。

    public void test(){
        this.showName1();    //成功调用
        this.showName2();    //成功调用
        this.showName3();    //成功调用
        this.showName4();    //报错,不能调用private方法
        super.showName1();   //成功调用
        super.showName2();   //成功调用 
        super.showName3();   //成功调用
        super.showName4();   //报错,不能调用private方法
    }

  当然,该方法还是需要用main方法中声明的变量调用。

    同样的,最重要的一点——在子类调用一个方法时,如果子类没有该方法,会一直向上寻找如果找到Object类还没有找到,就会报错(super直接忽略本类)如果在中间找到了一个private的方法,即使上面还有该方法,也不会再寻找了,而是直接报错

 举一个例子:

private void showName1(){  //在Student类中加入一个与Person类同名但不同修饰符的函数
    System.out.println("调用Student的private函数");
}
public class Pupil extends Student{  //继承Student
    public static void main(String[] args) {
        Pupil pupil = new Pupil();
        pupil.showName1();  //直接报错,寻找到Student就停了,而不是继续向Person寻找
    }
}

 3. 如果多个父类中有相同的成员,那么super的访问根据就近原则。

4. super和this的区别

方法重写/覆盖(override)

基本介绍

    方法覆盖就是子类有一个方法和父类的某个方法 名称、返回类型、参数一样,这样我们就说子类的这个方法覆盖了父类的那个方法。

使用细节

1. 子类方法的 形参列表,方法名称 要和父类的完全一样。

2. 子类方法的 返回类型 可以和父类方法的返回类型一样,或者是父类返回类型的子类

     public Object showName(){
         System.out.println("返回值为Object的父类方法");
         return "OK";
     }  //父类的方法

    public String showName(){
          System.out.println("返回值为String的子类方法");
          return "OK";
    }  //子类的方法

    public static void main(String[] args) {
        Student student = new Student();
        student.showName(); //调用
    }

    public String showName(){
         System.out.println("返回值为Object的父类方法");
         return "OK";
     }

    public Object showName(){
          System.out.println("返回值为String的子类方法");
          return "OK";
    }  //报错

3. 子类方法不能缩小父类方法的访问权限(但扩大可以)public > protected > 默认 > private

     public void showName(){
         System.out.println("修饰符为public的父类方法");
     } 

    protected void showName(){
          System.out.println("修饰符为protected的子类方法");
    }  //报错,减小了范围

 4. 重载和重写的比较

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值