浅谈Java中重写与重载的区别

重载和重写是Java中两个截然不同的概念。但是却因为名字相近导致很多人经常混淆。
下面用例子展示出他们之间的区别。
在Java中,重载(overloading) 发生在本类。方法名相同,参数列表不同,与返回值无关,只和方法名、参数列表、参数的类型有关。
重写(overriding) 发生在父类子类之间,一般都是表示子类和父类之间的关系,其主要的特征是:方法名相同,参数相同,但是具体的实现不同。

重载(overloading)

package day_11_26;

/**
 * @author soberw
 */
public class Overloading {

    /**
     * 以下方法构成重载
     */
    //初始方法
    public void sum() {

    }
    //构成重载,因为参数列表不同
    public void sum(int i) {

    }
    //报错,因为参数列表相同
//    public void sum(int a){
//
//    }

    //构成重载,因为参数类型不同
    public void sum(String i) {

    }
    //报错  重载跟方法有无返回值无关系
//    public int sum(int i){
//
//    }
    //构成重载 ,因为参数列表和长度都不同
    public void sum(int i,int j){

    }
    //报错 重载与修饰符无关
    protected void sum(int i){
        
    }
}

调用的时候,程序会根据你传入参数的类型来判断执行哪个函数,测试如下

package day_11_30;

/**
 * @author soberw
 */
public class OverloadingTest {
    public static void main(String[] args) {
        Overloading ol = new Overloading();
        ol.sum();
        ol.sum(1);
        ol.sum("str");
        ol.sum(1,3);
    }
}

运行结果:
在这里插入图片描述

注意事项:

1):方法名必须相同
2):方法的参数列表一定不一样
3):访问修饰符和返回值类型可以相同也可以不同。

重写(overriding)

首先,重写必须发生在子类和父类之间。最常见的例子,比如所有类都是继承Object类的,Object类中本身就有equals,hashcode,toString方法等.在任意子类中定义了同名同参的方法就构成方法重写。
比如我定义了三个类:
Person类

package day_11_30;

/**
 * @author soberw
 */
public class Person {
    public String name = "人类";

    public Person(){

    }

    public void show() {
        System.out.println("我是一个人");
    }

    //重载
    public void show(String name) {
        this.name = name;
        System.out.println("我是一个人,我的名字叫做" + name);
    }
    private void p1(int i){

    }
    public final void p2(){

    }
}


Man类,继承Person:

package day_11_30;

/**
 * @author soberw
 */
public class Man extends Person{
    String name = "张三";

    //报错,构造方法不能被重写
//    public Person(){
//
//    }
    //重写
    @Override
    public void show() {
        System.out.println("我是男人");
    }

    @Override
    public void show(String name) {
        this.name = name;
        System.out.println("我是一个男人,我的名字叫做" + name);
    }
    //重写权限不能小于父类
//    protected void show(String name) {
//        this.name = name;
//        System.out.println("我是一个男人,我的名字叫做" + name);
//    }
    
    //此处不算构成重写,只算定义了同名同参的方法,此方法与父类的无关系
    private void p1(int i){
        
    }

    //报错  最终的(final)不能被重写
//    public final void p2(){
//
//    }
}

Woman类,继承Person:

package day_11_30;

/**
 * @author soberw
 */
public class Woman extends Person{
    String name = "李红";
    //重写
    @Override
    public void show() {
        System.out.println("我是女人");
    }
}

测试:

package day_11_30;

/**
 * @author soberw
 */
public class Test {
    public static void main(String[] args) {
        Person p = new Person();
        p.show(p.name);
        p.show();
        Man m = new Man();
        m.show();
        m.show(m.name);
        Woman w = new Woman();
        w.show();
        w.show(w.name);
    }
}

运行结果:
在这里插入图片描述
我们发现,如果子类中重写了父类中的方法,那么子类调用的时候是调用重写后的(如Man类),如果子类中没有重写父类中的方法,那么子类调用的时候还是调用父类中的方法(如Woman类)。

注意事项:

1):方法名、返回值类型和参数列表必须相同。
2):访问权限不能比父类中被重写的方法低。
4):子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为private和final的方法。
5):父类的构造方法不能被子类重写。

posted @ 2022-02-09 19:45  soberw-  阅读(567)  评论(0编辑  收藏  举报