(这篇文章我已移动到了.net学习的栏目下,多态的思想是相通的,您看时如果对代码不解,只求您理解多态的思想就行,c#的多态思想借鉴此博文即可……)
老早就想写写对于多态的一些所思所想,这里没有多少教程般的俗话,就是一些自己的一些拙思吧……
多态(动态绑定)Style!(借鉴马士兵老师的教程所写,仅向马老师致敬!)
多态是Java中的一个重要的思想,不要觉得难,其实画画图就简单了,掌握好多态对于程序的健壮性及灵活性都是有好处的,不多说啦,谈谈我们的钓鱼岛吧!
例子代码:(程序只为最直观地简述多态的思想,不必细究。)
public class OwnerOfDiaoYuDao {
public static void main(String[] args) {
DiaoYuDao diaoyudao = new DiaoYuDao();
China china = new China();
diaoyudao.getHelp(china); //注意:此处子类china做为实参。
//即为父类的引用DiaoYuDao d指向了子类的对象。
}
}
class DiaoYuDao { //钓鱼岛
public void owner() {
System.out.println("Who is my owner?");
}
public void getHelp(DiaoYuDao d) {
d.owner();
}
}
class China extends DiaoYuDao{ //中国继承了钓鱼岛
public void owner() { //重写了owner()方法。
System.out.println("I'am your owner!");
}
}
内存分析:
一:多态,即为动态绑定,主要出现在父类的引用指向子类的对象中。如例中:diaoyudao.getHelp(china);此处的实参china能传递给父类的形参,就是因为china对象是DiaoYuDao的一个子类。diaoyudao.getHelp(china);执行完后内存见图中(1)线。注意(1)线指向china这个对象的父类对象,即d引用只认识china对象中的父类对象,而不认识china这个对象,这也就是所谓的“父类的引用指向子类的对象”。
二:如内存分析图,当执行diaoyudao.getHelp(china);时,会调用d.owner();问题出现了!如图,倒底是调父类的owner()还是调用子类的owner()呢?先看看运行结果吧!
哇,运行结果显示的是“I ' am your owner!”,由例子程序就知道,实际调用了子类中的owner()。为什么呢,按理说引用d只认识子类对象china中的父类对象,那么d.owner()应该调用父类owner()才对,但事实是你的这种想法确实是错了。这就是下面第三条要讲的动态绑定机制了!
三:多态真相(动态绑定):两个owner()都存在于代码区,调用方法时是去代码区去找相对应的方法。一开始时heap区中的china对象中的红色小区域指针是指向code segment中的父类owner()的,但当执行diaoyudao.getHelp(china);后,由于实际传的参数为子类对象china,所以会出现图中指针由(2)指向(3)的一个过程,此即为动态绑定的过程。所谓动态绑定的动态,即为只有在new出一个对象,如本例new出子类对象china后,实参传的是哪个对象,就调用哪个对象的方法。如本例,实参传的是子类对象,就调用的是子类中的owner();
总结:要想构成多态的存在要素,必须存在:
(1)存在继承。如China继承了父类DiaoYuDao。
(2)存在重写。如 China子类重写了父类的owner()方法。
(3)父类的引用要指向子类的对象。如diaoyudao.getHelp(china);如图中的(1)线处。
最后关于多态(动态绑定)的一点补充:钓鱼岛是中国的!