靜態綁定和動態綁定


一、綁定

  一個方法與類/對象聯系起來。

二、靜態綁定

  如果是private、static、final方法,編譯器可以准確的指導應該調用哪些方法,因為子類是不能重寫這些方法的,這種調用方法稱為靜態綁定(static binding)。

三、動態綁定

  調用的方法依賴於隱式參數的實際類型,並且在運行時實現動態綁定。

四、動態綁定過程

  虛擬機先在該對象的類中尋找是否有該方法,如果有直接調用,如果沒有則在超類中尋找。但如果每次調用方法都要進行搜索,時間開銷會相當大。因此虛擬機為每個類預先創建了一個方法表,其中列出了所有方法的簽名和實際調用的方法。
  Employee.java

 1 package test;
 2 import java.time.*;
 3 public class Employee {
 4     private String name;
 5     private double salary;
 6     private LocalDate hireDay;
 7 
 8     public Employee(String name, double salary, int year, int month, int day){
 9         this.name = name;
10         this.salary = salary;
11         this.hireDay = LocalDate.of(year,month,day);
12     }
13 
14     public Employee(){
15 
16     }
17     public String getName() {
18         return name;
19     }
20 
21     public double getSalary() {
22         return salary;
23     }
24 
25     public LocalDate getHireDay() {
26         return hireDay;
27     }
28 
29     public void raiseSalary(double byPercent) {
30         double raise = salary * byPercent / 100;
31         salary += raise;
32     }
33 
34 
35 
36 }

  Manager.java:

 1 package test;
 2 
 3 public class Manager extends Employee {
 4     private double bonus;
 5     public Manager(String name,double salary, int year, int month, int day){
 6         super(name,salary,year,month,day);
 7         bonus = 0;
 8     }
 9 
10     public Manager(){
11     }
12     
13     @Override
14     public double getSalary() {
15         double baseSalary = super.getSalary();
16         return baseSalary +bonus;
17     }
18 
19     public void setBonus(double b){
20         bonus = b;
21     }
22 }

  main.java

 1 package test;
 2 
 3 public class Main {
 4     public static void main(String[] args) {
 5         Manager boss = new Manager("Carl",8000,1987,12,15);
 6         boss.setBonus(5000);
 7         Employee[] staff = new Employee[3];
 8         
 9         staff[0] = boss;
10         staff[1] = new Employee("Harry", 5000, 1989, 10, 1);
11         staff[2] = new Employee("Harry", 4000, 1990, 3, 15);
12     
13         for(Employee e : staff)
14             System.out.println("name="+e.getName()+",salary="+e.getSalary());
15     }
16 
17 
18 }

  在main.java第14行調用e.getSalary()的過程:

  • 由於getSalary不是private、static或final方法,所以將采用動態綁定。
  • 虛擬機預先為Employee何Manager兩個類生成方法表。
    Employee:
      getName()  ->  Employee.getName()
      getSalary()  ->  Employee.getSalary()
      getHireDay()  ->  Employee.getHireDay()
      raiseSalary(double)  ->  Employee.raiseSalary(double)
    Manager:
      getName()  ->  Employee.getName()    (Manager沒有,從父類繼承)
      getSalary()  ->  Manager.getSalary()  (重寫了)
      getHireDay()  ->  Employee.getHireDay()
      raiseSalary(double)  ->  Employee.raiseSalary(double)
      setBonus(double)  ->  Manager.setBonus(double)     (Manager的方法)

    注意:這里的方法表省略了Object類的方法,所有的類都繼承自Object類
  • 首先虛擬機提取e的實際類型的方法表。既可能是Employee、Manager的方法表,也可能是Employee類的其他子類的方法表(本例中staff[0]是Manager,staff[1]、staff[2]是Employee)。
  • 接下來,虛擬機搜索定義getSalary簽名的類。調用該方法。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM