java多态及动态绑定

有关java多态学习的收获

is-a原则

"is-a"原则,它表明子类的每一个对象也是超类的一个对象。例如没一个经理都是雇员,因此将Manager设计为Employee的子类是不用多想的,反过来并不是没一个雇员都是经理。这一原则又叫做置换原则即程序中任何超类对象出现的位置都能用子类对象进行置换,例如:
Employee e;
e = new Employee();
e = new Manager();
在java程序设计语言中,对象变量是多态的。一个Employee变量可以引用一个Employee对象,也可以引用任何一个它的子类对象。(如:Manager等)
Manager boss = new Manager();
Employee[] e = new Employee[3];
e[0] = boss;
boss.setBonus(1000); //ok
e[0].setBonus(1000); //error
在编译器中e[0]被当做Employee对象,而Employee并没有一个叫做setBonus(double)的方法。
超类的引用不能赋给子类变量这是显然的。但是在一中特殊情况下编译器会接受这种操作
Manager[] m = new Manager[10];
Employee[] e = m;
e[0] = new Employee(“Tony”,…);
在这种情况下编译器却接受了这样的一种操作。

动态绑定

了解方法调用的过程很重要,下面让我们来详细了解一下调用过程:
1.编译器会首先查看对象的声明类型和方法名。如调用x.f(param),可能类中存在多个名为f但参数类型不同的方法,编译器会一一找到这些方法,包括父类的访问权限为public的同名方法。
2.编译器会根据调用的参数进行匹配,若找到一个完全匹配的方法就调用它,这个过程叫做重载解析。但是如果没有找到完全匹配的方法,就会经过一些类型转化进行匹配,如果能找到唯一匹配的方法就调用它,如果有多个匹配方法则报告一个错误。
3.如果是private,static,final方法或者构造方法,编译器可以准确得知道调用哪个方法,这就是静态绑定,与之相对的就是动态绑定。
4.当程序运行时,并且采用动态绑定时,虚拟机一定会调用与变量实际引用对象的实际类型最合适的那个方法,比如x是C类的一个对象,而C类是D类的子类,那么x.f()的调用,则是先匹配C类中的方法,如果找到直接调用,如果没有找到,则在D类中查找,找到了直接调用,否则在D类的超类中继续查找,以此类推。每一次的方法调用都需要进行搜索,时间开销非常大。因此虚拟机预先为没一个类穿件了一个方法表,其中列出了所有方法的签名和实际调用的方法,这样一来,每次调用的时候直接在对应的类的方法表中搜索匹配即可。
下面给出一个关于Employee和Manager的实例:
Employee:
getName()–>Employee.getName()
getSalary()–>Employee.getSalary()
getHireDay()–>Employee.getHireDay()
raiseSalary(double)–>Employee.raiseSalary(double)
Manager:
getName()–>Employee.getName()
getSalary()–>Manager.getSalary() Manager类重写了getSalary方法
getHireDay()–>Employee.getHireDay()
raiseSalary(double)–>Employee.raiseSalary(double)
setBonus(double)–>Manager.setBonus(double)
运行时e.getSalary()的调用过程
1.虚拟机提取e的实际类型的方法表。
2.虚拟机搜索getSalary方法进行匹配
3.虚拟机调用方法
动态绑定是一个非常重要的特性:无需对现有代码进行修改,就能对程序进行扩展。

学习自Java核心技术 卷I

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值