重载和重写有什么区别

技术博客 (227) 2023-12-24 18:01:01

重载和重写是Java中两个重要的概念。重载可以实现本类内的方法多态性,重写可以实现子类或实现类的多态性。

一、重载

在自然语言中,经常会出现“一词多义”的现象。比如:“墨水”,它可以指一种含有色素或染料的液体,墨水被用于书写或绘画;还可以指人的文化、知识,“胸无半点墨”便指人的知识很匮乏。一个词语如果有多重含义,那么就说该词语被重载了,具体代表什么含义需要结合具体的场景。在Java语言中,也存在重载,不过它需要满足以下几点:

1.方法名必须相同;

2.参数列表必须不同(参数的个数不同、参数的类型不同、类型的次序必须不同)

    public static void main(String[] args) {
        print(12);
        print("1234");
        print("hello Java!");
    }
    public static void print(int i){
        System.out.println("打印整型值:"+i);
    }
    public static void print(String s){
        System.out.println("打印字符串类型值:"+s);
    }
    public static void print(String s1,String s2){
        System.out.println("打印字符串类型值1"+s1+";字符串类型值2:"+s2);
    }

   //输出结果
   //打印整型值:12
   //打印字符串类型值:1234
   //打印字符串类型值:hello Java!

编译器在编译代码时,会对实参进行推演,会根据推演的结果来确定调用那个方法。

注意:重载与返回值类型是否相同无关;两个方法如果仅仅只是因为返回值类型不同,是不能构成重载的。具体错误如下所示:

public static void main(String[] args) {
    int a = 10;
    int b = 20;
    int ret = add(a, b);
    System.out.println("ret = " + ret);
 }
public static int add(int x, int y) {
    return x + y;
 }
public static double add(int x, int y) {
   return x + y;
 }
 

//编译错误
Test.java:已在类 TestDemo中定义了方法 add(int,int)
      public static double add(int x,int y){
1个错误

重载和重写有什么区别 (https://mushiming.com/) 技术博客 第1张

二、重写

重写(override):也称为覆盖。重写是子类对父类非静态、非private修饰,非final修饰,非构造方法等的实现过程进 行重新编写 , 返回值和形参都不能改变。即外壳不变,核心重写! 重写的好处在于子类可以根据需要,定义特定于自己的行为。 也就是说子类能够根据需要实现父类的方法。
方法重写的规则
1.子类在重写父类的方法时,一般必须与父类方法原型一致:修饰符 返回值类型 方法名(参数列表)要完全一致。
2.JDK7以后,被重写的方法返回值类型可以不同,但是必须是具有父子关系的访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类方法被public修饰,则子类中重写该方法就不能声明为 protected。
3.父类被static、private修饰的方法、构造方法都不能被重写。
4.子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为 private 和 fifinal 的方法。
5.子类和父类不在同一个包中,那么子类只能够重写父类的声明为 public 和 protected 的非 fifinal 方法。
6.重写的方法, 可以使用 @Override 注解来显式指定. 有了这个注解能帮我们进行一些合法性校验. 例如不小心将方法名字拼写错了 (比如写成 aet), 那么此时编译器就会发现父类中没有 aet 方法, 就会编译报错, 提示无法构成重写。
重写的具体实现代码如下:
//Animal.java
public class Animal {
    String name;
    int age;

    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void eat() {
        System.out.println(name + "吃饭");
    }
}
//Cat.java
public class Cat extends Animal {
    public Cat(String name, int age) {
        super(name, age);
    }

    @Override
    public void eat() {
        System.out.println(name + "吃鱼");
    }
}

//Dog.java
public class Dog extends Animal {
    public Dog(String name, int age){
        super(name, age);
    }

    @Override
    public void eat(){
       System.out.println(name+"吃骨头");
    }
}
//TestAnmal.java
public class TestAnimal {
    // 编译器在编译代码时,并不知道要调用Dog 还是 Cat 中eat的方法
    // 等程序运行起来后,形参a引用的具体对象确定后,才知道调用那个方法
    // 注意:此处的形参类型必须时父类类型才可以
    public static void eat(Animal a) {
        a.eat();
    }

    public static void main(String[] args) {
        Cat cat = new Cat("小黄", 2);
        Dog dog = new Dog("大黄", 3);
        eat(cat);
        eat(dog);
    }
}

//运行结果:
//小黄吃鱼
//大黄吃骨头

三、重载和重写的区别
区别点 重载       重写
参数列表 必须修改 一定不能修改
返回类型 可以修改 一定不能修改
访问限定符 可以修改 一定不能做更严格的限制(可以降低限制)
异常 可以修改 可以减少或者删除,一定不能抛出新的或者更广的异常
THE END

发表回复