Java方法重写(Override)详解(附带实例)
方法重写是指子类中定义了一个与父类中同名、同参数列表和同返回类型的方法,从而覆盖父类中该方法的实现。方法重写也叫作方法覆盖。
在某些情况下,父类提供的方法并不适用于子类。例如:
2) 访问权限不能比父类中被重写的方法更严格,访问权限可以相同或更宽松:
【实例】在使用继承的前提下,继续实现方法重写,代码如下:
Java 程序中,有以下两点需要注意:
在某些情况下,父类提供的方法并不适用于子类。例如:
public class Animal { // 定义私有的属性:name private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } // 定义成员方法:eat 方法 public void eat() { System.out.println("Animal 动物吃东西"); } } public class Cat extends Animal { @Override public void eat() { System.out.println("Cat 猫吃猫粮"); } // 子类中特有的方法 public void sleep() { System.out.println("猫在睡觉"); } }在程序中,Animal 类提供的属性和方法并不一定适用于 Cat 类,因为不同动物吃的东西是不同的,所以 Cat 类中的 eat() 方法需要考虑 Cat 吃的是猫粮,所以需要覆盖该方法。
Java方法重写的规则与要求
1) 方法名称、参数列表和返回类型必须与父类中被重写的方法完全一致:- 方法名称相同:只有在子类中重写的方法与父类中的方法具有相同的名称,才能实现方法的覆盖;
- 参数列表相同:参数的数量、类型和顺序必须与父类中的方法完全一致。如果参数列表不同,那么将是一个重载的方法,而不是重写;
- 返回类型相同或子类型:在 Java 5 及以上的版本中,重写的方法可以返回父类方法返回类型的子类型,但不是严格意义上的相同返回类型。然而,当返回类型为基本数据类型时,必须完全相同。
2) 访问权限不能比父类中被重写的方法更严格,访问权限可以相同或更宽松:
- 如果父类中的方法是公共的,那么子类中重写的方法可以是公共的、受保护的或包访问权限(默认访问权限,没有特定关键字修饰),但不能是私有的(private);
- 如果父类中的方法是受保护的,那么子类中重写的方法可以是受保护的或公共的,但不能是私有的或包访问权限更严格的情况。
Java方法重写的实现
通过子类对象调用被重写的方法时,实际执行的是子类中重写后的方法,而不是父类中的原始方法。这是 Java 运行时多态性的体现。【实例】在使用继承的前提下,继续实现方法重写,代码如下:
public class Animal { // 定义私有的属性:name private String name; public Animal() { System.out.println("Animal Constructor"); } public Animal(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } // 定义成员方法:eat 方法 public void eat(){ System.out.println("Animal 动物吃东西"); } } public class Cat extends Animal{ public Cat() { System.out.println("Cat Constructor"); } public Cat(String name) { super(name); } @Override public void eat() { System.out.println("Cat 猫吃猫粮"); } // 子类中特有的方法 public void sleep(){ System.out.println("猫在睡觉"); } }程序运行结果为:
Animal Constructor
Cat Constructor
Cat 猫吃猫粮
Java 程序中,有以下两点需要注意:
- 子类的覆盖方法不能使用比父类中被覆盖的方法更严格的访问权限,子类方法的可见性应与父类保持一致或大于父类;
- 对构造方法来说,在创建子类对象时,程序一定会先调用父类的构造方法,再调用子类的构造方法。如果子类没有在代码中明确调用父类的构造方法,则父类必须提供无参数构造方法给子类隐式调用(若不提供构造方法,程序会自动提供并完成调用)。