美文网首页
Overriding in Java

Overriding in Java

作者: zac4j | 来源:发表于2017-05-25 00:05 被阅读13次

    原文:geeks4geeks

    子类可以重新定义父类的方法,这种属性被称为方法重写(Overriding)。签名(返回类型,参数类型,参数数量)保持和父类中定义的一致,完成方法重写以实现运行时多态(重写的方法是根据调用它的对象被调用,而不是根据它的引用类型)。

    // 简单的演示重写的例子
    
    // 父类
    class Parent{
      void show() { 
        System.out.println("Parent's show()"); 
      }
    }
    
    // 子类
    class Child extends Parent{
      // 重写父类的方法
      void show() { 
        System.out.println("Child's show()");
      }
    }
    
    // 测试类
    class Test {
      public static void main(String[] args) {
        // 如果父类引用父类的对象,则父类的 show 方法被调用
        Parent obj1 = new Parent();
        obj1.show();
        // 如果父类引用子类的对象,则子类的 show 方法被调用
        // 这种被称为运行时多态
        Parent obj2 = new Child();
        obj2.show();
      }
    }
    

    输出:

    Parent's show()
    Child's show()
    
    一些有趣的事实:
    • C++ 中需要 virtual 关键字以实现重写或运行时多态。Java 中方法默认是 virtual 的。
    • 可以有多级的重写:
    // 简单的演示多级重写的例子
    
    // 父类
    class Parent {
      void show() {
        System.out.println("Parent's show()");
      }
    }
    
    // 子类
    class Child extends Parent {
      // 重写父类的方法 
      void show() {
        System.out.println("Child's show()");
      }
    }
    
    // 孙类
    class GrandChild extends Child {
      // 重写子类的方法
      void show() { 
        System.out.println("GrandChild's show()");
      }
    }
    
    // 测试类
    class Test {
      public static void main(String[] args) {
        Parent obj1 = new GrandChild();
        obj1.show();
      }
    }
    

    输出:

    GrandChild's show()
    
    • 如果不想让一个方法被重载,可以用 final 关键字修饰它
    // 简单的演示 final 关键字重写的例子
    
    class Parent {
      // 不能被重写
      final void show() { }
    }
    
    class Child extends Parent {
      // 会产生错误
      void show() { }
    }
    
    

    输出:

    error: show() in Child cannot override show() in Parent
      void show() {  }
           ^
      overridden method is final
    
    • 重写的方法的访问限制不能收窄,只能扩大。如父类中是 protected 方法 ,子类不能以 private 限制符重写方法。
    • Private 的方法不能被重写,因为在 private 方法在编译时绑定会它的引用类型。
    • 我们可以给子类中与父类相同签名的方法加上 static 关键词,但这不认为是重写,因为没有任何运行时多态。
    • 我们可以在重写的方法中使用 super 关键字调用父类的方法。
    // 简单的例子演示 super 关键字重写的例子
    
    // 父类
    class Parent {
    void show() {
      System.out.println("Parent's show()");
      }
    }
    
    // 子类
    class Child extends Parent {
    // 重写父类的 show 方法
      void show() {
        super.show();
        System.out.println("Child's show()");
      }
    }
    
    // 测试类
    class Test {
      public static void main(String[] args) {
        Parent obj = new Child();
        obj.show();
      }
    }
    
    

    输出:

    Parent's show()
    Child's show()
    

    应用

    重写的方法允许我们调用任何派生类的方法,甚至不必知道派生类对象的种类。

    JavaOVerriding.jpg

    上图的管理软件中基类 Employee 有不同的方法,如 raiseSalary(), transfer(), promote(), salary()等。不同的子类 Manager 和 Clerk 可能对这些父类的方法有自己的实现。在实际使用场景中,我们只需要传递一份完整的员工名单,而不必知道他所属的类型是 Manager 或 Clerk 之类的。例如,我们只需通过遍历名单给每位员工 raiseSalary(),每位员工都有自己的 raiseSalary() 逻辑,我们不必知道每个员工对应的类型。每个员工只要有 raiseSalary() 方法,便会被调用。

    // 简单的演示重写应用的例子
    
    // 基类
    class Employee {
      public static int base = 10000;
      int salary() {
        return base;
      }
    }
    
    // 派生类
    class Manager extends Employee {
      // This method overrides show() of Parent
      int salary() {
        return base + 20000;
      }
    }
    
    // 派生类
    class Clerk extends Employee {
      // This method overrides show() of Parent
      int salary() {
      return base + 10000;
      }
    }
    
    // 测试类
    class Test {
      // 打印雇员的薪资
      static void printSalary(Employee e) {
        System.out.println(e.salary());
      }
    
      public static void main(String[] args) {
        Employee obj1 = new Manager();
        System.out.print("Manager's salary : ");
        printSalary(obj1);
    
        Employee obj2 = new Clerk();
        System.out.print("Clerk's salary : ");
        printSalary(obj2);
      }
    }
    

    输出:

    Manager's salary : 30000
    Clerk's salary : 20000
    

    相关文章

      网友评论

          本文标题:Overriding in Java

          本文链接:https://www.haomeiwen.com/subject/kocaxxtx.html