如果子类与基类具有相同的方法,则称为method overriding Or 换句话说,如果子类为其父类之一中存在的任何方法提供特定实现,则称为method overriding
让我们从一个实时示例开始:
在小型组织中,有两种员工,即Manager 和Developer 。现在我们要打印员工的工资。
在 org.arpit.java2blog 中创建类 Employee.java Employee.java
package org.arpit.java2blog;
public class Employee {
int employeeId;
String employeeName;
double salary;
public Employee(int employeeId, String employeeName, double salary) {
super();
this.employeeId = employeeId;
this.employeeName = employeeName;
this.salary = salary;
}
public int getEmployeeId() {
return employeeId;
}
public void setEmployeeId(int employeeId) {
this.employeeId = employeeId;
}
public String getEmployeeName() {
return employeeName;
}
public void setEmployeeName(String employeeName) {
this.employeeName = employeeName;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
}
Manager.java:
package org.arpit.java2blog;
public class Manager extends Employee{
public static final double BONUSPERCENT=0.2;
public Manager(int employeeId, String employeeName, double salary) {
super(employeeId, employeeName, salary);
}
public double getSalary() {
return salary+salary*BONUSPERCENT;
}
}
Developer.java:
package org.arpit.java2blog;
public class Developer extends Employee{
public static final double BONUSPERCENT=0.1;
public Developer(int employeeId, String employeeName, double salary) {
super(employeeId, employeeName, salary);
}
public double getSalary() {
return salary+salary*BONUSPERCENT;
}
}
MethodOverridingMain:
package org.arpit.java2blog;
public class MethodOverridingMain {
/**
* @author Arpit Mandliya
*/
public static void main(String[] args) {
Developer d1=new Developer(1,"Arpit" ,20000);
Developer d2=new Developer(2,"John" ,15000);
Manager m1=new Manager(1,"Amit" ,30000);
Manager m2=new Manager(2,"Ashwin" ,50000);
System.out.println("Name of Employee:" +d1.getEmployeeName()+"---"+"Salary:"+d1.getSalary());
System.out.println("Name of Employee:" +d2.getEmployeeName()+"---"+"Salary:"+d2.getSalary());
System.out.println("Name of Employee:" +m1.getEmployeeName()+"---"+"Salary:"+m1.getSalary());
System.out.println("Name of Employee:" +m2.getEmployeeName()+"---"+"Salary:"+m2.getSalary());
}
}
运行它: 当你将运行 MethodOverridingMain.java。你将得到以下输出:
Name of Employee:Arpit—Salary:22000.0
Name of Employee:John—Salary:16500.0
Name of Employee:Amit—Salary:36000.0
Name of Employee:Ashwin—Salary:60000.0
正如您在此处看到的,我们在 Developer 和 Manager 中重写了 Employee 类的 getSalary() 方法。为什么我们需要重写 getSalary()? 因为我们需要基于 Class 的 getSalary() 方法的具体实现。例如 Developer 类和 Manager 类有不同的好处,所以我们需要对两者进行不同的实现。
方法覆盖的规则
Arguments |
Must not change |
Return type |
Can’t change except for covariant (subtype) returns |
Access Modifier |
Must not be more restrictive. Can be less restrictive. |
Exceptions |
Can reduce or eliminate but must not throw new/broader checked exceptions |
Contructor |
Can not be overriden |
Static method |
Can not be overriden |
final method |
Can not be overriden |
现在在这里,我将回答您可能提出的一些显而易见的问题:
问题
为什么不能使访问修饰符更具限制性(例如从公共到私人)?
这是 OOP 中的一个基本原则:子类是父类的完整实例,因此必须至少具有与父类相同的接口。不那么显眼会违反这个想法;您可以使子类无法用作父类的实例。 让我们借助示例来看看:
class Employee{
public double getSalary(){
//some operation
}
}
class Developer extends Employee{
private double id getSalary(){
//some operation
}
}
现在我可以调用使用:
Employee e1=new Developer();
e1.getSalary();
因此,即使您将开发人员的 getSalary() 方法设为私有,即使您已将其设为私有,您也可以使用 Employee(超类)的引用访问开发人员的 getSalary() 方法。所以你不能在覆盖方法时减少访问修饰符。
为什么不能覆盖静态方法?
因为静态方法与类相关而不是对象的状态,所以您可以在子类中声明静态方法,但它与父类无关。它是方法隐藏而不是覆盖。
你能覆盖私有方法吗?
不,你不能。私有方法不能被覆盖,因为它在任何其他类中都不可见。您可以为您的子类声明一个与超类方法无关的新方法。所以它不是方法覆盖。
为什么不能覆盖最终方法?
因为最终方法不应该被覆盖。您声明一个最终方法是因为您不希望它在子类中被覆盖。
如果我们改变参数的数量怎么办?
如果您更改参数的数量,那么它将是方法重载而不是覆盖。父类方法和子类方法应该具有相同的方法签名。
什么是动态绑定?
在运行时发生的重写方法的绑定称为动态绑定。
超级关键词
super 关键字可用于从子类调用特定的父类方法。
例如:
package org.arpit.java2blog;
public class Employee{
public double getSalary(){
System.out.println("In Employee class getSalary() method");
return 0;
}
public static void main(String args[])
{
Developer d1=new Developer();
d1.getSalary();
}
}
class Developer extends Employee{
public double getSalary(){
// calling parent class method
super.getSalary();
System.out.println("In Developer class getSalary() method");
return 0;
}
}
运行程序时,您将获得以下输出:
In Employee class getSalary() method
In Developer class getSalary() method
这就是java中的方法覆盖。
|