Java面试之Java基础4——重载与重写的区别

目录

重载与重写的概念

重载与重写的区别

重载与重写的总结

构造器是否能被重写override

为什么函数不能根据返回类型来区分重载


重载与重写的概念

重载:同样一个方法可以根据输入参数列表的不同,做出不同的处理。普通方法和构造器方法都能够重载。

方法重载:

/**
 * 重载方法
 */
public class Print {
    public void print(String str) {
        System.out.println(str);
    }

    public void print(Integer i) {
        System.out.println(i);
    }

    public void print(Float f) {
        System.out.println(f);
    }

    public void print(Boolean b) {
        System.out.println(b);
    }
}

构造器重载

/**
 * 重载构造器
 */
public class Print {
    Print(String str){
        System.out.println(str);
    }

    Print(Integer i){
        System.out.println(i);
    }
    
    Print(Float f){
        System.out.println(f);
    }

    public void print(Boolean b) {
        System.out.println(b);
    }
}

重写:重写是要在子类继承父类的同名方法时,当输入参数列表一样时,要做出不同于父类的逻辑功能,就是覆盖重写父类方法。注意:重写的方法上有一个@Override,表示该方法被重写了。

/**
 * 方法重写
 */
class Father {
    public void print(){
        System.out.println("Father");
    }

    public void print(String str){
        System.out.println("Father -> "+str);
    }
}

class Son extends Father {
    // 重写print()方法
    @Override
    public void print() {
        System.out.println("Son");
    }

    // 重写print(String str)方法
    @Override
    public void print(String str) {
        System.out.println("Son -> "+str);
    }
}

重载与重写的区别

重载的注意事项:发生在同一个类中,方法名必须相同

扫描二维码关注公众号,回复: 12455079 查看本文章
  • 方法重载与下列因素相关:
    • 1. 参数个数不同
    • 2. 参数类型不同
    • 3. 参数的多类型顺序不同
  • 方法重载与下列因素无关:
    • 1. 与参数的名称无关
    • 2. 与方法的返回值类型无关

下面是错误示例:

上面这句话严格来说是错误的,因为参数个数相同,但可以是类型不同

下面是参数个数相同,参数类型相同,但是顺序不同。

参数名称即使不同,但参数类型、参数列表、参数个数相同,也会报错

即使返回类型不同,但方法名相同,参数类型、参数列表、参数个数相同,也会报错

重写注意事项:发生在运行期,是两个及以上的类,是子类对父类允许访问的方法进行重新编写。方法名、参数列表、参数顺序必须相同,子类方法返回值类型比父类方法返回值类型更小或相等

  • 抛出异常范围小于等于父类,访问修饰符范围大于等于父类。
  • 如果父类方法访问修饰符为private/final/static,则子类不能重写该方法,但是被static修饰的方法能够被再次声明。
  • 构造方法无法被重写
  • 重写的方法上有一个@Override表示该方法被重写了。

下面是关于重写特点的代码解释。

1、抛出异常范围小于等于父类

  • 子类抛出异常范围等于父类抛出异常范围,不会报错。

  • 子类抛出异常范围小于父类抛出异常范围,不会报错。

  • 子类抛出异常范围大于父类抛出异常范围,会报错。

2、访问修饰符范围大于等于父类

访问修饰符的范围:public > protected > private

  • 子类访问修饰符的范围大于父类访问修饰符的范围,不会报错

  • 子类访问修饰符的范围等于父类访问修饰符的范围,不会报错

  • 子类访问修饰符的范围小于父类访问修饰符的范围,会报错

3、如果父类方法访问修饰符为private/final/static,则子类不能重写该方法,但是被static修饰的方法能够被再次声明

  • 使用private修饰的无法重写

  • 使用final修饰的无法重写

  • 使用static修饰的不能重写,但能被再次声明

下面的代码也不能称之为重写:当向上转型时,调用的还是父类的方法。

class Father {
    static void print() {
        System.out.println("Father");
    }
}

class Son extends Father {
    static void print() {
        System.out.println("Son");
    }
}

public class Demo {
    public static void main(String[] args) {
        Son.print();
        Father son=new Son();
        son.print();
    }
}
/*
 * 打印结果:
 * Son
 * Father
 */

在Java中,如果父类含有一个静态方法,且在子类中也含有一个返回类型,方法名、参数列表等都与之相同的的静态方法,在子类中只是对父类的该同名方法进行隐藏,并不是重写。父类与子类含有的其实是两个没有关系的方法,两者的行为不具有多态性。

在上面的例子中,print方法与类发生了关联,但它不在乎什么类型的类正在创建它,而仅在乎引用的类型。在Father son = new Son()中,son是类Son在内存中的一个Father类型的引用,如果一个static修饰的方法被调用了,JVM不会检查什么类型正在指向它,只会调用与Father类相关联的方法的实例。

4、⼦类⽅法返回值类型应⽐⽗类⽅法返回值类型更⼩或相等

如果⽅法的返回类型是void和基本数据类型,则返回值重写时不可修改。但是如果⽅法的返回值是引⽤类型,重写时是可以返回该引⽤类型的⼦类的。

class Father {
    public String print() {
        return "Father";
    }
}

class Son extends Father {
    @Override
    public String print() {
        return "Son";
    }
    
    public Father father(){
        return new Father();
    }
}

class SonSon extends Son {
    @Override
    public String print() {
        return "SonSon";
    }

    @Override
    public Father father() {
        return new Son();
    }
}

重载与重写的总结

  重载 重写
概念 发生在一个类中。一个方法根据输入参数列表的不同,做出不同的逻辑处理。普通方法和构造器都能够重载 发生在子类和父类中。子类方法继承父类的同名方法,重新写方法的处理逻辑。普通方法能够重写,构造器不能够重写。
特征 普通方法重载方法名相同;构造器重载与类名相同。 重写的方法上有一个@Override注解,表示该方法被重写了。
相关因素 方法重载与参数个数、参数类型、多类型参数的顺序的不同相关。(即方法的参数列表要不一样) 方法重写与参数个数、参数类型、多类型参数的顺序的相同相关。(即方法的参数列表要一样)
不相关因素 方法重载与参数的名称、方法的返回值类型无关。(即重载方法的参数名称、返回值类型是否一样不重要) 方法重写的参数名称可以改变,但返回值类型要小于等于父类方法的返回值类型。
其他 可以抛出不同的异常,可以有不同修饰符。 子类抛出的异常范围要小于等于父类,访问修饰符的范围要大与等于父类。如果父类方法被private/final/static修饰,那么子类不能重写该方法。

构造器是否能被重写override

构造器Constructor 不能被 override(重写),但是可以 overload(重载),所以你可以看到⼀个类中有多个构造函数的情况。

构造器可以重载

 

为什么函数不能根据返回类型来区分重载

为什么不能根据返回类型来区分重载?因为调用时不能指定类型信息,编译器不知道你要调用哪个函数。

当执行add(1, 2)这个方法时,不需要保存返回值,那么该调用哪个方法呢?这很好不区分吧。

如果需要返回值,比如说float sum = add(1, 2);还好区分些,至少可以根据前面的float推断出要调用哪个方法。但如果不需要返回值,那么几乎难以区分。

如果方法的返回值不加以利用,那么返回值将毫无用处,自然无法作为区别的标准

更多的适合方法的返回值是函数运行后的一个结果,是方法的调用者和被调用者通信的关键,并不能作为某个方法的唯一标识。

猜你喜欢

转载自blog.csdn.net/cnds123321/article/details/113388238