第三章java中的方法覆盖


如果子类与基类具有相同的方法,则称为method overridingOr 换句话说,如果子类为其父类之一中存在的任何方法提供特定实现,则称为method overriding

让我们从一个实时示例开始:

在小型组织中,有两种员工,即ManagerDeveloper。现在我们要打印员工的工资。

img

在 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中的方法覆盖。


原文链接:https://codingdict.com/