以x.f(args)为例
1、编译器查看对象的声明类型和方法名
- 编译器会一一列举所有名为f的方法和超类中名为f可访问的方法
2、确定方法调用中提供的参数类型
- 就是args的参数类型,int就用f(int a),String就用f(String a)
- 编译器也会考虑类型转换的问题,但是如果转换后有多个方法匹配会报错
3、静态绑定&动态绑定
- 静态绑定:如果是private、statict、final方法,编译器可以准确知道该调用哪个方法
- 动态绑定:如果调用的方法依赖隐式参数的实际类型,必须在运行中使用动态绑定
https://blog.csdn.net/sted_zxz/article/details/77980124 静态绑定与动态绑定详解
https://blog.csdn.net/qq_37499840/article/details/89218587 private、static、final关键字理解,private不能继承、重写,static不能重写,final不能重写,帮助理解静态绑定
4、动态绑定使用方法表调用方法
- 需要找到与动态绑定参数类型一致的方法,在当前类、当前类超类中寻找。
- 虚拟机预先为每个类计算了一个方法表,方便快速调用。
以这下面这段为例,
- 虚拟机获取boss实际类型的方法表
- 查找定义了getSalary()签名的类
- 虚拟机调用此方法。
因为没有参数,所以没有重载解析相关内容。
public class EmployeeTest {
public static void main(String args[]){
Manager boss = new Manager("Marker", 80000, 1987, 12, 15);
boss.getSalary();
}
}
class Employee
{
// 字段
private String name;
private double salary;
// 构造器
public Employee(String n, double s, int year, int month, int day)
{
name = n;
salary = s;
}
// 封装的实现,通过get set方法操作字段
public String getName()
{
return name;
}
public double getSalary()
{
return salary;
}
public void raiseSalary(double byPercent)
{
double raise = salary * byPercent / 100;
salary += raise;
}
}
class Manager extends Employee
{
private double bonus;
/**
* @param name the employee's name
* @param salary the salary
* @param year the hire year
* @param month the hire month
* @param day the hire day
*/
public Manager(String name, double salary, int year, int month, int day)
{
super(name, salary, year, month, day);
bonus = 0;
}
public double getSalary()
{
double baseSalary = super.getSalary();
return baseSalary + bonus;
}
public void setBonus(double b) // 这个setBonus就是Manager特有的,Employee对象就不能使用这个方法
{
bonus = b;
}
}
网友评论