清华大学第二版

源代码在线查看: 多态性.txt

软件大小: 4194 K
上传用户: sinba
关键词: 清华大学
下载地址: 免注册下载 普通下载 VIP

相关代码

				运行时多态性是面向对象程序设计代码重用的一个最强大机制,动态性的概念也可以被说成“一个接口,多个方法”。Java实现运行时多态性的基础是动态方法调度,它是一种在运行时而不是在编译期调用重载方法的机制,下面就继承和接口实现两方面谈谈java运行时多态性的实现。
				
				    一、通过继承中超类对象引用变量引用子类对象来实现
				
				    举例说明:
				
				    //定义超类superA
				    class superA
				    {
				    int i = 100;
				    void fun()
				
				    {
				    System.out.println(“This is superA”);
				    }
				    }
				    //定义superA的子类subB
				    class subB extends superA
				    {
				    int m = 1;
				    void fun()
				
				    {
				    System.out.println(“This is subB”);
				    }
				    }
				    //定义superA的子类subC
				    class subC extends superA
				    {
				    int n = 1;
				    void fun()
				
				    {
				    System.out.println(“This is subC”);
				    }
				    }
				    class Test
				    {
				    public static void main(String[] args)
				
				    {
				    superA a;
				    subB b = new subB();
				    subC c = new subC();
				    a=b;
				    a.fun(); (1)
				
				    a=c;
				    a.fun(); (2)
				
				    }
				    }
				    运行结果为:
				
				    This is subB
				    This is subC
				    上述代码中subB和subC是超类superA的子类,我们在类Test中声明了3个引用变量a, b, c,通过将子类对象引用赋值给超类对象引用变量来实现动态方法调用。也许有人会问:“为什么(1)和(2)不输出:This is superA”。java 的这种机制遵循一个原则:当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法。
				
				    所以,不要被上例中(1)和(2)所迷惑,虽然写成a.fun(),但是由于(1)中的a被b赋值,指向了子类subB的一个实例,因而(1)所调用的fun()实际上是子类subB的成员方法fun(),它覆盖了超类superA的成员方法fun();同样(2)调用的是子类subC的成员方法fun()。
				
				    另外,如果子类继承的超类是一个抽象类,虽然抽象类不能通过new操作符实例化,但是可以创建抽象类的对象引用指向子类对象,以实现运行时多态性。具体的实现方法同上例。
				
				    不过,抽象类的子类必须覆盖实现超类中的所有的抽象方法,否则子类必须被abstract修饰符修饰,当然也就不能被实例化了。
				
				
				
				关于think in java 中的多态性的问题
				 悬赏分:50 - 解决时间:2007-6-28 21:23
				Shape c = new Circle()和Circle c = new Circle()有何区别?? 
				
				我做了如下测试: 
				package net.qday.test; 
				public class Shape { 
				
				public Shape(){ 
				System.out.println("create a new shape"); 
				} 
				public void draw(){ 
				System.out.println("shape drawing"); 
				} 
				} 
				package net.qday.test; 
				public class Circle extends Shape{ 
				public Circle(){ 
				System.out.println("create a new circle"); 
				} 
				public void draw(){ 
				System.out.println("circle drawing"); 
				} 
				public static void main(String[] args){ 
				Circle c = new Circle(); 
				c.draw(); 
				System.out.println("------------------"); 
				Shape s = new Circle(); 
				s.draw(); 
				} 
				} 
				运行结果如下(没看出来什么区别): 
				create a new shape 
				create a new circle 
				circle drawing 
				------------------ 
				create a new shape 
				create a new circle 
				circle drawing
				问题补充:我在Circle里面增加了另一个方法draw2(),确实,在main里,s.draw2不可以,c.draw2可以。还有其它区别吗? 
				还有一点,我就更不明白了,即然Shape s = new Circle()不可以用Circle里面新加的一些方法,那为什么我看别人的代码经常还都这么写,而不是Circle c = new Circle()?这么写的目的到底是为了干什么?
				提问者: chamble - 试用期 一级 最佳答案
				Shape c = new Circle()和Circle c = new Circle()有何区别?? 
				
				怎么说 Shape c = new Circle()来说吧 
				
				Shape c 创建一个Shape 的对象 c 但是他的实例也是是Shape 类的.因为Circle是继承自Shape 的. 但是c只能调用到所有Shape 中的方法.而Circle中间的方法是没有办法调用到的..要是如果Circle重写了Shape 中间的方法的话调用执行的还是子类的方法. 
				
				Shape c = new Circle(); 
				在理解一下...Shape 不光可以是一个类.也可以是一个虚类.或者说说一个接口.而Circle是必须继承或者实现了Shape 的一个类. 
				
				补充一下..个人认为多态不一定是必须只有继承才可以实现的 
				
				public void draw(){ 
				System.out.println("circle drawing"); 
				} 
				
				public void draw( int a){ 
				System.out.println("circle drawing"+a); 
				} 
				我想这也是多态的一种表现吧..通过方法的重写.. 
				至于为什么...我想想要..我也经常这么用但还没有总结过.. 
				一般我是用接口去进行这种操作.因为接口没有办法实例化.. 
				所以要实例化一个他的实现.. 
				
				xxpniu 说的到有那么点点感觉..例子很不错.. 
				我复述一下..学校是一个类.一个老师就是一个接口.N个老师就是N个接口.这个学校实现n个老师和其他的接口.但是你得到学校就能得到老师这是肯定的.老师 c = new 学校();就好比用学校直接得到了老师.. 
				省心啊..不用在学校里面去辛辛苦苦的去找一个老师出来了..直接就能得到了老师...差不多这意思吧..
				回答者:little902 - 经理 五级 6-28 16:17
				提问者对于答案的评价:多谢~!也多谢其它几位。评价已经被关闭    目前有 0 个人评价
				       好
				50% (0) 不好
				50% (0) 
				相关问题
				?  A program is a specific set of instructions 
				对最佳答案的评论    共 1 条
				good!
				评论者: sadshine - 魔法学徒 一级 其他回答    共 3 条
				我想问一下你到底知道什么叫多态吗? 
				多态的意思就是多种形态,也就是同样的一个消息, 
				发送给不同的对象导致不同的行为,实际上,你给出的例子就是 
				典型的多态的例子,在Java中,多态是基于继承的基础上的,在C++中还 
				需要虚函数的支持。 
				有了继承,也就有了向上类型转换, 
				所以一个继承了Shape类的Circle类所产生的对象可以直接 
				赋给Shape,这是因为原型也是一种图形。多态采用的是动态联编,也就是 
				在运行时候才确定所调用的行为。 
				
				Circle s = new Circle(); 
				这里产生了一个Circle类,同时调用的是默认的Circle()构造函数, 
				在该构造函数中会自动调用super(),也就是父类的构造函数,所以 
				执行顺序为 
				create a new shape 
				create a new circle 
				最后调用了draw方法,执行下列行为 
				circle drawing 
				
				Shape s = new Circle(); 
				这里也是同样道理,new Circle()也是产生了一个Circle对象,所以 
				执行的前两句结果跟上面的那个例子一样,关键就是Shape的引用所调用 
				的方法draw,这就体现了多态了,通过动态联编,在运行时确定了它所指向 
				的对象是Circle,所以调用的自然也就是Circle中的draw方法啦。
				回答者:mqp179698202 - 举人 四级 6-28 14:45
				Circle 类里的 
				Shape s = new Circle(); 
				应该写成 
				Shape s = new Shape(); 
				这样的显示结果是不同的。 
				
				
				Shape s = new Circle(); 
				这样的写法是上溯类型,本质上这样还是建一个子类:Circle 
				所以draw()方法还是调用的子类Circle的方法。 
				所以打印的效果是一样的 
				
				楼上两位说的比较深刻,建议采用楼下两位的意见!
				回答者:neusunly - 助理 二级 6-28 14:51
				希望这个能对学java的同志们有个帮助 
				我把类和事例做个比喻 
				类就好比学校的组织结构的一个规范. 
				中学肯定有高一高二但这是存在学校设计上的 
				这就好比定义了一个类 
				而现实中的一个学校就是一个实例.我们可以根据学校的结构来找到相关的负责人,比如高三年级年级组长 
				类的继承好比某个学校多了个少年班 之前的组织结构就必须扩充 
				然而这个学校仍旧可以按之前的组织找到高三年纪. 
				但是你不能用小学的组织结构放在一个高中学校上. 
				你也不能把有少年班的组织结构来找没有少年班的学校 
				大概就这些比较乱 
				
				最终要明白 类只是一中数据结构,是给电脑看的 让电脑知道怎么去存取数据. 
				该怎么去操作数据.对象(实例)是一种放在机器里面的数据组合.是我们操作的对象.所以我们操作对象(实例)就必须告诉电脑,数据的结构			

相关资源