Java--理解方法调用

1.弄清楚如何在对象上应用方法调用非常重要。下面假设要调用x.f(args),心事参数x声明为类C的一个对象,下面是分析调用过程

1)编译器查看对象的声明类型和方法名,假设调用x.f(param),且隐式参数x声明为C的对象。需要注意的是,有可能存在对个名字的f,但参数类型不一样的方法,俗称:重载。注意(超类的私有方法不可访问)

2)接下来,编译器查看调用方法时提供的参数类型,如果在所有名为f的方法中存在一个与提供的参数类型完全匹配,就选择这个方法。这个过程叫重载解析

2。方法的名字和参数列表称为方法的签名。如果在子类中定义了一个与父类名称相同的方法,那么子类中的这个方法就覆盖了父类中的这个相同名字的方法。不过返回类型不是名字的一部分,因此覆盖方法时,一定要保证返回类型的兼容性,允许子类将覆盖方法的返回类型定义为原返回类型的的子类型,如:

public class Car {
    private String name ="汽车";
    public Car echo() {
    	return  new Car();
		
	}
public class BMWCar extends Car {
	public BMWCar echo() {
    	// TODO Auto-generated method stub
    	   return new BMWCar();
    }

可以看出 echo这个方法被后面的BMWCar覆盖了,我们说这两个echo方法具有可协变(妥协,被迫的类型)的返回类型

3.调用方法的解析过程
 

首先Employee里的所有方法:getName->Employee.getName()

                                                 getSa->Employee.getSa()

                                                 getHa->Employee.getHa()

                                                  rS(double)->Employee.rS(double)

然后Manager的: getName->Employee.getName()

                              getSa->Employee.getSa()

                              getHa->Employee.getHa()

                              rS(double)->Employee.rS(double)
                              sB(double)->Manager.sB(double)

在运行时,调用employee.getSa()解析:

1,首先,虚拟机提取employee的实际类型的方法表。既可能是Employee,Manager的方法表。也有可能是Employee类的其他子类的方法表

2,然后,虚拟机搜索定义getSa的类。此时,虚拟机已经知道应该调用哪个方法

3,最后,虚拟机调用方法。

注意:动态绑定有一个非常重要的特性:无需对现存的代码进行修改,就可以对程序进行扩展

警告:再覆盖一个方法的时候,子类方法不能低于父类方法的可见性。特别是,如果父类方法是public,子类方法一定声明为public。经常会发生这类错误:在声明子类方法的时候,遗漏了public修饰符。此时,编译器将会把它解释为试图提供更严格的访问权限。

猜你喜欢

转载自blog.csdn.net/qq_33188563/article/details/81147056
今日推荐