Java 重写

Java 重写

在上一章中,我们讨论了超类和子类。如果一个类从其超类继承一个方法,那么就有机会覆盖该方法,前提是它没有被标记为final。

覆盖的好处是:能够定义一个与子类类型特定的行为,这意味着子类可以根据自己的需求实现父类方法。

在面向对象的术语中,覆盖意味着覆盖现有方法的功能。

示例

让我们来看一个示例。

class Animal {
   public void move() {
      System.out.println("Animals can move");
   }
}

class Dog extends Animal {
   public void move() {
      System.out.println("Dogs can walk and run");
   }
}

public class TestDog {

   public static void main(String args[]) {
      Animal a = new Animal();   // Animal reference and object
      Animal b = new Dog();   // Animal reference but Dog object

      a.move();   // runs the method in Animal class
      b.move();   // runs the method in Dog class
   }
}

这将会产生下面的结果 −

输出

Animals can move
Dogs can walk and run

在上面的示例中,你可以看到,即使 b 是Animal的一种,它也会运行Dog类中的move方法。原因是:在编译时,检查的是引用类型。然而,在运行时,JVM会找出对象的类型,并执行属于特定对象的方法。 因此,在上面的示例中,程序将正确编译,因为Animal类具有move方法。然后,在运行时,它运行特定于该对象的方法。 考虑以下示例−

示例

class Animal {
   public void move() {
      System.out.println("Animals can move");
   }
}

class Dog extends Animal {
   public void move() {
      System.out.println("Dogs can walk and run");
   }
   public void bark() {
      System.out.println("Dogs can bark");
   }
}

public class TestDog {

   public static void main(String args[]) {
      Animal a = new Animal();   // Animal reference and object
      Animal b = new Dog();   // Animal reference but Dog object

      a.move();   // runs the method in Animal class
      b.move();   // runs the method in Dog class
      b.bark();
   }
}

这将产生以下结果 –

输出

TestDog.java:26: error: cannot find symbol
      b.bark();
       ^
  symbol:   method bark()
  location: variable b of type Animal
1 error

由于b的引用类型Animal没有名为bark的方法,所以这个程序将会在编译时报错。

方法重写的规则

  • 参数列表必须与被重写方法的参数列表完全相同。

  • 返回类型必须与被重写方法的返回类型相同或是其子类型。

  • 访问修饰符不能比被重写方法的访问修饰符更严格。例如:如果父类方法声明为public,则子类中的重写方法不能是private或protected。

  • 只有继承了父类的子类才能重写实例方法。

  • 声明为final的方法不能被重写。

  • 声明为static的方法不能被重写,但可以重新声明。

  • 如果一个方法不能被继承,则它也不能被重写。

  • 在同一包中的子类可以重写任何非private或final的父类方法。

  • 在不同包中的子类只能重写父类中声明为public或protected的非final方法。

  • 重写方法可以抛出任何未检查异常,而不管被重写方法是否抛出异常。然而,重写方法不应抛出已被重写方法声明的新的或更宽的已检查异常。重写方法可以抛出比被重写方法更窄或更少的异常。

  • 构造方法不能被重写。

使用super关键字

在调用被重写方法的父类版本时,使用 super 关键字。

示例

class Animal {
   public void move() {
      System.out.println("Animals can move");
   }
}

class Dog extends Animal {
   public void move() {
      super.move();   // invokes the super class method
      System.out.println("Dogs can walk and run");
   }
}

public class TestDog {

   public static void main(String args[]) {
      Animal b = new Dog();   // Animal reference but Dog object
      b.move();   // runs the method in Dog class
   }
}

这将产生以下结果−

输出

Animals can move
Dogs can walk and run

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程