由于最近很长一段时间忙于他事,对java的有些机制的概念的理解模糊了些,甚至有些遗忘了,现在终于可以转入正轨,今天在读一段代码时,看到了如下的情况(由于公司保密要求,故不泄露具体函数名称和实现细目,只暴露我遇见的问题):
Interface A {
abstract void f();
}
class B implements A{
void f(){
//body;
.......
.......
//body end
}
}
public calss c {
public static void main(String[] args){
B b = new B();
A a = (A)b;
a.f();
}
}
我当时的问题是:
当A a = (A)b时,b发生了向上转型行为,故此时b被窄化,此时reference a 持有的对象应该只有其父接口中的函数有效,这是没有异议的,那么,当main中发生的调用
a.f()被执行时,真正唤起的函数式抽象函数f(),还是B中的f().
经过参阅资料和我自己的验证,得到的结论是:a.f()最终唤醒了B中的f();
通过思考和继续学习,我得到了如下的认识:
1、“向上转型”发生在编译期,子类被窄化后在型别上被视为其超类,窄化后在原子类中但不在其超类中的函数失效;但由其超类继承而来的接口依然可以被唤起。
2、子类向上转型后,其通过继承并覆写后的函数仍能被唤起,并能被准确识别及执行,即向上转型后的对象,其内有效的函数别调用时,能准确执行其自身未转型时的功能。
这个机制主要由java函数(非final函数)的“后期邦定”性质保障。
3、这个机制的优越处在于:当父类的一个接口函数被不同子类继承并覆写后,当个个子类通过向上转型时,只要唤醒父类接口,java虚拟机会自动准确的识别出究竟该调用那个具体的子类函数。
4、后期邦定依靠于执行期型别识别。这个概念我将于以后做出补充。
5、以上就是所谓的多态的一部分内容。
目前,我所了解到的多态带来的意义是:
开发变得容易些了,当很多不同的类要执行只有细小差别的功能的同名函数时,可以提供一个接口并暴露接口函数(那个细小差别函数的同名函数)作为公共接口函数,其他不同的类可以继承并覆写那个接口,调用时,只需将这些类的对象向上转型,调用该接口即可,java机制会保证调用准确。这样做使得代码量减小,可读性提高。