Java继承中方法的覆盖和重载

    |     2015年3月30日   |   Java面向对象   |     0 条评论   |    1336

继承里,子类可以改写从父类拿来的方法:名称、返回值类型、参数列表都相同,功能却不同。这就叫覆盖(override)。参数列表(类型、个数、顺序)有一项不同,就不再是覆盖,而可能构成重载(overload)。

覆盖不会把父类方法从内存里删掉,只是对子类实例暂时隐藏。子类里要调用被盖住的父类版本,用 super。

一、覆盖示例

构造方法不能继承,子类通过 super(name) 调用父类构造。Dog 覆盖了 Animal 的 say():

public class Demo {
    public static void main(String[] args) {
        Dog myDog = new Dog("花花");
        myDog.say();  // 子类实例走子类方法

        Animal myAnimal = new Animal("贝贝");
        myAnimal.say();  // 父类实例走父类方法
    }
}
class Animal {
    String name;
    public Animal(String name) {
        this.name = name;
    }
    public void say() {
        System.out.println("我是一只小动物,我的名字叫" + name + ",我会发出叫声");
    }
}
class Dog extends Animal {
    public Dog(String name) {
        super(name);
    }
    public void say() {
        System.out.println("我是一只小狗,我的名字叫" + name + ",我会发出汪汪的叫声");
    }
}
// 运行结果:
// 我是一只小狗,我的名字叫花花,我会发出汪汪的叫声
// 我是一只小动物,我的名字叫贝贝,我会发出叫声

二、覆盖原则

  • 方法名、参数列表必须与父类相同。返回类型通常也相同;Java 5 起允许协变返回(子类返回类型是父类返回类型的子类型)。
  • 覆盖方法的访问权限不能比原方法更窄。
  • 覆盖方法不能抛出比原方法更多(更宽)的受检异常。
  • final 方法不能覆盖。
  • 父类方法若是 private,子类里同名方法只是新方法,并不构成覆盖。
  • static 不能覆盖。一边 static、一边实例,即使其它条件都像覆盖,也会编译错误。两边都是 static 时满足「同名同参」也只是隐藏,编译期按引用类型绑定。

父类和子类里的方法还会一起参与重载。例如父类有 func(),子类有 func(int i),这是重载,不是覆盖。

三、覆盖 vs 重载

对比项 覆盖 override 重载 overload
参数列表 必须一致 必须不一致
返回类型 相同或协变 无要求(但不能只靠它区分)
发生位置 子类对父类 同一类中的方法(含继承来的)
权限 / 异常 有限制 无这些限制
次数 一个父方法在一个子类里覆盖一次 可以多次重载

一句话总结:覆盖是子类用相同签名改写父类方法;重载是同名不同参。一个看继承,一个看参数列表。

转载请注明来源:Java继承中方法的覆盖和重载
本文链接地址:https://ai.zhousir.top/?p=82

上一篇:

下一篇:

回复 取消