精华内容
下载资源
问答
  • 面向对象多态性

    千次阅读 2017-12-25 21:16:12
    2. 面向对象多态性 3. 抽象类与接口   A.Object类  ·Object类是所有Java类的根基类(“祖先类”)  ·如果在类的声明中未使用extends关键字指明其基类,则  默认基类为Object类    a.to

    学习目标:

    1. Object类的toString()与equals(Object  obj)方法

    2. 面向对象的多态性

    3. 抽象类与接口

     

    A.Object类

         ·Object类是所有Java类的根基类(“祖先类”)

         ·如果在类的声明中未使用extends关键字指明其基类,则

           默认基类为Object类

          

         a.toString方法

            1.Object类中定义有public  String toString()方法,

              其返回值是String类型,描述当前对象的有关信息

           ***如果直接打印某对象的引用,则默认会调用这个对象的

              toString()方法,默认打印的内容中包含这个引用所指

              向的内存地址

             


             


                 

     

           2.可以根据需要在用户自定义类中重写toString()方法

           


           

                                 

         b.equals( )方法

            1.Object类中定义有publicboolean equals(Object obj)

              方法,提供定义对象是否“相等”的逻辑

           2.Object的equals方法定义为:x.equals(y),当x和y指向同

             一个地址时返回true,否则返回false

           3.String类中已经重写了equals(Object obj)方法,重写后的

             方法比较的是两个字符串的内容是否一样

             (注意:==比较对象的引用)

           4.可以根据需要在用户自定义类型中重写equals方法

             

                

    B.多态性

         ·封装是为了保护属性的一种操作,继承是为了扩展类的功能

         ·是由封装性继承性引出的面向对象程序设计语言的另一种特征

         a.多态的体现

           1.从方法的角度来看

             ·方法的重载和重写

              (1)重载(overloading):根据传入的参数不同,完成的

                                      功能也不同

              (2)重写(override):子类根据需求重写父类中的方法

           2.从对象的角度来看

             ·对象的多态性主要分为两种:

              (1)向上转型:子类对象--->父类对象(程序会自动完成)

                    格式:父类  父类对象=子类实例

                   或者  父类  父类对象=new 子类

                ***向上转型后,因为操作的是父类对象,所以无法找

                   到在子类中定义的新方法;但如果子类重写了父类的

                   某个方法,则调用的是重写后的方法  

            

            

            

            

      

         

         

             

              (2)向下转型:父类对象--->子类对象 (必须明确的指明转型的子类类型)

                   格式:子类  子类对象=(子类)父类实例

                   注意:向下转型前先要向上转型

       


        

         

             

         b.instanceof关键字

           1.在java中可以使用instanceof关键字判断一个对象是否属于一个类的实例

           2.格式:对象  instanceof  类--->返回boolean类型

         


            


            

        


              

        c.final关键字

           1.在JAVA中声明类、属性和方法时,可以使用关键字final来修饰

           2.注意:

             (1)final修饰变量(成员变量或局部变量),则成为

                  常量,只能赋值一次

                  final 类型  variableName;

                  修饰成员变量时,定义时同时给出初始值,而修饰

                  局部变量时不做要求

                                                  

             (2)final修饰方法,则该方法不能被子类重写

                  final 返回值类型  methodName(paramList)

                  {

                      …

                  }

                  

                  

             (3)final修饰类,则类不能被继承

                  final classfinalClassName{

                      …

                  }

                              

                   

    C.抽象类与接口

        ·用abstract修饰的类即为抽象类

             abstract class 抽象类名{

             }

     

        ·抽象类不能被实例化,必须被继承,抽象方法必须被重写,生成它

          的子类

        ·abstract修饰的方法就是抽象方法,抽象方法没有方法体

        ·抽象类不一定要包含抽象方法,若类中包含了抽象方法,则该类必须

          被定义为抽象类

        ·如果一个子类没有实现抽象父类中所有的抽象方法,则子类也成为一

          个抽象类

        ·构造方法、静态方法、私有方法、final方法不能被声明为抽象的方法

                          


                        


                        

                         

                                 

          ***如果子类也是一个抽象类,则可以不用重写父类的抽象方法,但是

             当子类的子类为非抽象类时,子类的子类要重写子类的抽象方法,

             并且要将子类未重写的父类的抽象方法也写上

             


             

         a.接口

            ·接口(interface)是抽象方法和常量值的定义的集合

            ·接口是一种“标准”、“契约”。

            ·从本质上讲,接口是一种特殊的抽象类,这种抽象类中只能包含

              常量和方法的定义,而没有变量和方法的实现

            1.接口的声明语法

              (1)包括接口声明和接口体

              (2)完整的接口声明:

                [public] interface接口名称[extends listOfSuperInterface] { … }

              (3)接口体包括常量定义和方法定义

                   ·常量定义: typeNAME=value;  该常量被实现该接口的多

                     个类共享; 具有public,final, static的属性.

                   ·方法体定义:具有 public和abstract属性

            2.接口的实现类

              (1)与抽象类一样,接口要使用也必须通过子类,子类通过

                   implements关键字实现接口

              (2)一个类可以实现多个接口,implements子句中用逗号分开

              (3)非抽象子类必须实现接口中定义的所有方法

              (4)实现格式:

                   ·class子类 implements接口A,接口B…{

                     }

            3.接口的使用规则

              (1)接口中所有的方法都是public abstract 

              (2)在接口中声明方法时,不能使用static,final,synchronized,

                   private,protected等修饰符

              (3)一个接口可以继承自另一个接口

              (4)java中不允许类的多继承,但允许接口的多继承

              (5)接口中可以有数据成员,这些成员默认都是public static final

            4.接口的用途

              (1)通过接口实现不相关类的相同行为,而无需考虑这些类之间的关系

              (2)通过接口指明多个类需要实现的方法

              (3)通过接口了解对象的交互界面,而无需了解对象所对应的类

            5.eg1:

                 

                 

                 

                 

                 

                  

              eg2:

                 

                 

                 

                  

                  

              eg3:

                 

                 

                  

                  

                   

                   

              eg4:

                  

                  

                   

                   

                    

                     

           

     

            

            

      

             

               

    展开全文
  • Java之对象多态性(使用生活中通俗的例子讲解)

    万次阅读 多人点赞 2018-04-03 12:48:49
    Java之对象多态性多态概念 (Java)多态(英语:polymorphism),是指计算机程序运行时,相同的消息可能会送给多个不同的类别之对象,而系统可依据对象所属类别,引发对应类别的方法,而有不同的行为。简单来说,...

     

     

    多态概念 (Java)


        多态英语:polymorphism),是指计算机程序运行时相同的消息可能会送给多个不同的类别之对象,而系统可依据对象所属类别,引发对应类别的方法,而有不同的行为。简单来说,所谓多态意指相同的消息给予不同的对象会引发不同的动作称之

    多态也可定义为“一种将不同的特殊行为和单个泛化记号相关联的能力”。

    多态可分为变量多态与函数多态。变量多态是指:基类型的变量(对于C++是引用或指针)可以被赋值基类型对象,也可以被赋值派生类型的对象。函数多态是指,相同的函数调用界面(函数名与实参表),传送给一个对象变量,可以有不同的行为,这视该对象变量所指向的对象类型而定。因此,变量多态是函数多态的基础。

     

     

    例子


        比如有动物(Animal)之类别(Class),而且由动物继承出类别鸡(Chicken)和类别狗(Dog),并对同一源自类别动物(父类别)之一消息有不同、的响应,如类别动物有“叫()”之动作,而类别鸡会“啼叫()”,类别狗则会“吠叫()”,则称之为多态。

     

    概括


        上面关于多态的概念看起来有那么一点难以理解,但是我们可以把上述一大段话给归纳成为一句话就是:相同的消息可能会送给多个不同的类别之对象,而系统可依据对象所属类别,引发对应类别的方法,而有不同的行为

    例如:比如有动物(Animal)之类别(Class),而且由动物继承出类别鸡(Chicken)和类别狗(Dog),并对同一源自类别动物(父类别)之一消息有不同的响应。

     

     

    解释


            方法的覆盖特性是Java在运行时支持的多态性之一。系统动态的调度方法是由调用一个被覆盖的方法引起的,该调用机制发生在运行时,而不是编译时。

     

    • 当一个被覆盖的方法通过一个父类引用调用时,Java决定执行哪个版本的方法(父类的方法或者被子类覆盖的方法)取决于方法调用发生时,被引用的对象的类型。因此,这一决定实在运行期间做出来的。
    • 在运行期间,哪个版本的被覆盖的方法将会被执行是由被引用的对象的类型决定的而不是引用的类型(值)。
    • 一个父类的引用可以引用一个子类的对象,这也是一些人口中所说的“向上转型”,Java用这个方法来解决程序运行时覆盖方法被调用的问题。

     

        因此,如果一个父类包含了一个被子类覆盖的方法,接下来通过一个父类的引用值来引用其不同的子类对象,父类引用调用被覆盖的方法时,不同版本的被覆盖的方法将会执行。下面是一个例子,简单的阐述一下这种动态方法分配机制:

    OUTPUT(输出):

     

     

    程序详解


        上面的这个程序创建了一个名为A的父类以及两个分别名为B,C的子类。这两个子类都覆盖了父类A类的m1方法

    1.在main()方法里面的Dispatch类中,首先声明了A类,B类,C类的三个对象。

        此时的引用及对象之间的关系如下图所示:

     

     

        其中,A类引用指向了一个A类对象,B类引用指向了一个B类对象,B类对象内包含了一个从A类中继承下来的m1()方法以及自己覆盖m1的方法;C类引用指向了一个C类对象,C类对象内也包含了一个从A类中继承下来的m1()方法以及自己覆盖m1的方法;

    2.现在声明一个名为ref的A类的引用,起初它将会指向一个空指针。

    3.接下来我们将用A类引用来一个一个地指向每一种对象(A类B类或者C类),并且通过这个A类引用ref来调用m1()方法。正如输出所显示的那样,到底执行哪一个版本的m1()方法是由此时引用指向的对象的类型所决定的。

     

     

     

     

     

     

     

    亲自动手验证


         

               有兴趣的同学可以点击此处进行试验去这个在线IDE平台自己试一下这串代码,亲自动手验证一下上面这个例子。

     

     

     

    运行时成员变量的多态性


     

     

     

        在Java中,我们只能够覆盖父类的方法,却不能覆盖父类的成员变量。

    所以运行时,成员变量无法实现多态性。举一个例子:

        

        在上面这个例子中,子类B类虽然覆盖了父类A类的成员变量X,然而通过A类引用去调用B类对象的X时返回的并不是B类中已经覆盖了A类的那个X的值,返回的仍然是父类A类中的X值,也就是说,成员变量覆盖无法实现像方法覆盖那样的多态性。虽然A类(父类)和B类(子类)都有一个公共的变量x,我们实例化一个B类对象并用一个A类引用a指向它。因为变量没有被覆盖,所以“a.x”这一句话总是代表父类的数据成员。

     

    OUTPUT(输出):


     

     

     

    亲自试一试


            

        有兴趣的同学可以点击此处通过在线IDE平台亲自实验一下,更好的理解这个例子。

     

    静态VS动态绑定


     

        1.静态绑定发生在程序的编译期间,而动态绑定发生在程序的运行期间。

        2.private,final,static方法以及变量通过编译器实现静态绑定,同时覆盖方法与运行时运行的对象类型所绑定。

     

     

    对于多态的通俗理解


            其实,对于引用的理解,我们可以简单的理解其为一个“遥控器”,每个“遥控器”可以与一个对象进行“配对”,并通过遥控器来控制对象的“行为”。例如,按下空调遥控器的开关键,空调就会开启。就好比调用 空调遥控器.开机()方法使得空调遥控器指向的空调对象执行开机()方法一样。

     

     

     

     

    多态的误区点


     

      其中,对象能够执行哪些方法是由引用的类型所决定的,而对象具体怎样去执行某个方法,却是由对象自己决定的。

     

        例如下面这段程序:

    class A {
        public void fun1() {
            System.out.println("A-->public void fun1(){}");
        }
    
        public void fun2() {
            this.fun1();
        }
    }
    
    class B extends A {
        public void fun1() {
            System.out.println("B-->public void fun1(){}");
        }
    
        public void fun3() {
            System.out.println("B-->public void fun3(){}");
        }
    }
    
    public class JavaExample {
        public static void main(String[] args) {
            A a = new B();
            a.fun1();
        }
    }
    
    

       

    执行结果为:B-->public void fun1(){};

     上面的程序中,定义了父类为A类,子类为B类,子类B覆盖了父类的fun1()方法,添加了自己的fun3()类,这是一个对象向上转型的关系,但是A类型的引用a虽然可以调用fun1()方法,但是不能通过A类引用a调用子类对象独有的fun3()方法!!!

    因此,我们可以得出下面这个结论:

        引用所能够调用的方法取决于引用的类型,而如何具体的实现该方法取决于对象的类型。

    引用a为A类型,所以通过引用a只能调用A类型中包含的方法( fun1()和fun2()),而能调用B类中的fun3(。也就是说A类引用只能向指向的对象发送A类中包含的方法,具体的实现由指向的对象的类型来决定。

       

                        点击此处进入在线IDE实验本案例。

    我们可以在上面的实验中,执行a.fun3(),将会提示找不到fun3()方法。

     

    向下转型的要求


     

        还是上面的这一串代码,我们只更改其main()函数中的代码:

     

    public class JavaExample {
        public static void main(String[] args) {
           A a=new B();
           B b=(B)a;
           b.fun1();
           b.fun2();
           b.fun3();
        }
    }
    
    

        B类为A类的子类,上面的a首先被声明为一个A类型的引用,并指向一个B类型的对象,接下来把A类引用通过向下转型变成一个B类引用,从而有权利去调用B类中非共有的方法。

        然而,在看下面这一段代码,还是只更改main()函数中的代码:

    public class JavaExample {
        public static void main(String[] args) {
           A a=new A();
           B b=(B)a;
           b.fun1();
           b.fun2();
           b.fun3();
        }

        上面的这一段代码也实现了向下转型,然而运行时却报错了:

    Exception in thread "main" java.lang.ClassCastException: A cannot be cast to B

    at JavaExample.main(JavaExample.java:26)

    错误提示说A类引用无法被转换成B类引用,这又是怎么回事呢?

    我们发现两端代码的不同之处就在于第一段代码中是

     A a=new B();

    而第二段代码中是:

     

      A a=new A();

        初始化的对象不同而已,因为在对象进行向下转型时,必须首先发生对象向上转型,否则将出现对象转换异常。

    第二段代码中,A类型引用指向的是一个A类对象,把A类引用转换成B类引用,此时就可以发送调用B类方法的命令给指向的对象,而指向的对象为A类对象却并不含B类中非共有的方法,对象根本就没有实现这个方法,怎么去执行方法呢?因此就会产生错误。

        可以用上述遥控器的例子来简单的理解一下这个问题:

          假设最开始只有一个老式遥控器,遥控器只有1.打开空调,2.关闭空调,3.制冷三个功能,遥控器向空调发送相应的命令,空调收到命令后执行相应的动作。

        此时类似于执行语句 A a=new A( );

      

        接下来,老式空调太旧了,空调厂商在老式空调的基础上,开发了一款新式空调,不仅有老式空调的三个功能,而且还加入了1.制热功能和2.加湿功能这两个功能。

        此时类似于语句 class B extend A;

        然而,我们此时只有老式空调的遥控器,但是我们还是可以用老式空调的遥控器与操作新式空调,类似于A a=new B( )这个操作,因为新式空调是继承与老式空调改造而来的,我们仍然能够使用老式空调的遥控去操控新式空调,只不过老式空调上只有最基础的三个功能,不能操纵新式空调执行其新添加的加热和加湿功能,但是仍然还是可以使用的。

            如果,我们需要使用新式空调的新增的加热和加湿功能,那么我们理应更换新式空调对应的遥控器就好了。

    此时类似于 B b=(B) a;

        

       此时的情况就类似于调用b.makeCold( )方法了。

        上面是正常的向下转型,然而,如果我们不向上转型而直接向下转型会发生什么样的情况呢?

        例如:A a=new A( );

                    B b=(B)a;

                就发生了下面这种情况:

     

        此时,如果新式空调遥控器向老式空调发送一个加热的指令,然而老式空调收到指令后却发现并没有加热的功能,此时就会发生系统故障。

            所以,总结而之一句话:在对象进行向下转型时,必须首先发生对象向上转型,否则将出现对象转换异常。

     

    基础不牢?新手不友好?无人带路?关注《扬俊的小屋》公众号吧!


     

    参考资料


        1.维基百科-多态

        2.https://www.geeksforgeeks.org/dynamic-method-dispatch-runtime-polymorphism-java

            作者:Gaurav Miglani   翻译:刘扬俊

        3.《Java开发实战经典》 李兴华著  清华大学出版社

     

     

    博客文章版权说明


     

     

     

    第一条 本博客文章仅代表作者本人的观点,不保证文章等内容的有效性。

    第二条 本博客部分内容转载于合作站点或摘录于部分书籍,但都会注明作/译者和原出处。如有不妥之处,敬请指出。

    第三条 征得本博客作者同意的情况下,本博客的作品允许非盈利性引用,并请注明出处:“作者:____转载自____”字样,以尊重作者的劳动成果。版权归原作/译者所有。未经允许,严禁转载

    第四条 对非法转载者,“扬俊的小屋”和作/译者保留采用法律手段追究的权利

    第五条 本博客之声明以及其修改权、更新权及最终解释权均属“扬俊的小屋”。

    第六条 以上声明的解释权归扬俊的小屋所有。

     

     

     

    展开全文
  • 封装:封装是一种信息隐蔽技术,它体现于类的说明,是对象的重要特性。封装使数据和加工该数据的方法(函数)封装为一个整体,以实现独立很强的模块,使得用户只能见到对象的外特性(对象能接受哪些消息,具有...

    封装性:封装是一种信息隐蔽技术,它体现于类的说明,是对象的重要特性。封装使数据和加工该数据的方法(函数)封装为一个整体,以实现独立性很强的模块,使得用户只能见到对象的外特性(对象能接受哪些消息,具有哪些处理能力),而对象的内特性(保存内部状态的私有数据和实现加工能力的算法)对用户是隐蔽的。封装的目的在于把对象的设计者和对象的使用者分开,使用者不必知晓其行为实现的细节,只须用设计者提供的消息来访问该对象。

    继承性:继承性是子类共享其父类数据和方法的机制。它由类的派生功能体现。一个类直接继承其他类的全部描述,同时可修改和扩充。继承具有传递性。继承分为单继承(一个子类有一父类)和多重继承(一个类有多个父类)。类的对象是各自封闭的,如果没继承性机制,则类的对象中的数据、方法就会出现大量重复。继承不仅支持系统的可重用性,而且还促进系统的可扩充性。

    多态性:对象根据所接收的消息而做出动作。同一消息被不同的对象接受时可产生完全不同的行动,这种现象称为多态性。利用多态性用户可发送一个通用的信息,而将所有的实现细节都留给接受消息的对象自行决定,如是,同一消息即可调用不同的方法。例如:同样是 run 方法,飞鸟调用时是飞,野兽调用时是奔跑。多态性的实现受到继承性的支持,利用类继承的层次关系,把具有通用功能的协议存放在类层次中尽可能高的地方,而将实现这一功能的不同方法置于较低层次,这样,在这些低层次上生成的对象就能给通用消息以不同的响应。在 OOPL 中可通过在派生类中重定义基类函数(定义为重载函数或虚函数)来实现多态性。

    展开全文
  • C#中多态性的实现

    2021-01-20 02:01:05
    多态是指一个行为具有多个不同表现形式的能力,在C#中通过多态性的检测时机可以分为静态多态性和动态多态性 静态多态性:函数重载和运算符重载 动态多态性:抽象方法、重写方法、隐藏方法 二:函数重载(overlode) ...
  • C#类的多态性详解

    2021-01-20 06:39:52
    第一种:编译时的多态性,直接这样说不知道说啥?程序执行过程主要分为三步:编译,链接,运行。在编译时体现的多态性是通过方法的重载来实现的。方法的重载我们听过,就是一个类对象调用若干同名,但参数类型、个数...
  • 面向对象JAVA多态性

    千次阅读 2011-12-29 12:21:40
    数据抽象、继承和多态是面向对象程序设计语言的三大特性。多态,我觉得它的作用就是用来将接口和实现分离开,改善代码的组织结构,增强代码的可读性。在某些很简单的情况下,或许我们不使用多态也能开发出满足我们...
    数据抽象、继承和多态是面向对象程序设计语言的三大特性。多态,我觉得它的作用就是用来将接口和实现分离开,改善代码的组织结构,增强代码的可读性。在某些很简单的情况下,或许我们不使用多态也能开发出满足我们需要的程序,但大多数情况,如果没有多态,就会觉得代码极其难以维护。 
    

     

    在Java中,谈论多态就是在讨论方法调用的绑定,绑定就是将一个方法调用同一个方法主体关联起来。在C语言中,方法(在C中称为函数)的绑定是由编译器来实现的,在英文中称为early binding(前期绑定),因此,大家自然就会想到相对应的late binding(后期绑定),这在Java中通常叫做run-time binding(运行时绑定),我个人觉得这样称呼更贴切,运行时绑定的目的就是在代码运行的时候能够判断对象的类型。通过一个简单的例子说明:

     

    /**

     

     * 定义一个基类

     

     */

     

    public Class Parents {

     

      public void print() {

     

        System.out.println(“parents”);

     

    }

     

    }

     

    /**

     

     * 定义两个派生类

     

     */

     

    public Class Father extends Parents {

     

      public void print() {

     

        System.out.println(“father”);

     

    }

     

    }

     

    public Class Mother extends Parents {

     

      public void print() {

     

        System.out.println(“mother”);

     

    }

     

    }

     

    /**

     

     * 测试输出结果的类

     

     */

     

    public Class Test {

     

      public void find(Parents p) {

     

        p.print();

     

    }

     

    public static void main(String[] args) {

     

      Test t = new Test();

     

      Father f = new Father();

     

      Mother m = new Mother();

     

      t.find(f);

     

      t.find(m);

     

    }

     

    }

     

    最后的输出结果分别是father和mother,将派生类的引用传给基类的引用,然后调用重写方法,基类的引用之所以能够找到应该调用那个派生类的方法,就是因为程序在运行时进行了绑定。

     

    学过Java基础的人都能很容易理解上面的代码和多态的原理,但是仍有一些关键的地方需要注意的,算是自己对多态的一个小结:

     

    1.        Java中除了static和final方法外,其他所有的方法都是运行时绑定的。在我另外一篇文章中说到private方法都被隐式指定为final的,因此final的方法不会在运行时绑定。当在派生类中重写基类中static、final、或private方法时,实质上是创建了一个新的方法。

     

    2.在派生类中,对于基类中的private方法,最好采用不同的名字。

     

    3.包含抽象方法的类叫做抽象类。注意定义里面包含这样的意思,只要类中包含一个抽象方法,该类就是抽象类。抽象类在派生中就是作为基类的角色,为不同的子类提供通用的接口。

     

    4.对象清理的顺序和创建的顺序相反,当然前提是自己想手动清理对象,因为大家都知道Java垃圾回收器。

     

    5.在基类的构造方法中小心调用基类中被重写的方法,这里涉及到对象初始化顺序。

     

    6.构造方法是被隐式声明为static方法。

     

    7.用继承表达行为间的差异,用字段表达状态上的变化。

      

    如何理解Java多态性?通过类型转换,把一个对象当作它的基类对象对待。
    从相同的基类派生出来的多个派生类可被当作同一个类型对待,可对这些不同的类型进行同样的处理。
    这些不同派生类的对象响应同一个方法时的行为是有所差别的,这正是这些相似的类之间彼此区别的不同之处。

    动态绑定


    将一个方法调用和一个方法主体连接到一起称为绑定(Binding)。
    根据绑定的时机不同,可将绑定分为“早期绑定”和“后期绑定”两种。
    如果在程序运行之前进行绑定(由编译器和链接程序完成),称为早期绑定。
    如果在程序运行期间进行绑定,称为后期绑定,后期绑定也称为“动态绑定”或“运行时绑定”。
    在Java中,多态性是依靠动态绑定实现的,即Java
    虚拟机在运行时确定要调用哪一个同名方法。

    多态的应用


    由于多态性,一个父类的引用变量可以指向不同的子类对象,并且在运行时根据父类引用变量所指向对象的实际类型执行相应的子类方法。
    利用多态性进行二次分发。
    利用多态性
    设计回调方法。

    多态的例子


    Shape类是几个具体图形类的父类

    package cn.edu.uibe.poly;

    public class Shape {
     public void draw(){
      System.out.println("Shape.draw()");
     }

    }
     

    Rectangle类是Shape类的一个子类

    package cn.edu.uibe.poly;
    public class Rectangle extends Shape {
     @Override
     public void draw() {
      System.out.println("画矩形");
     }
     
    }
     

    Circle类也是Shape类的子类

    package cn.edu.uibe.poly;
    public class Circle extends Shape{
     @Override
     public void draw() {
      System.out.println("画圆");
     }
    }
     

    Triangle类是Shape类的另外一个子类


    package cn.edu.uibe.poly;
    public class Triangle extends Shape{
     @Override
     public void draw() {
        System.out.println("画三角形");
     }
    }
     

    ShapeDemo类中随机生成矩形、圆、三角形,然后用Shape类型的引用调用。

    package cn.edu.uibe.poly;  
    import java.util.*;  
    public class ShapeDemo {  
        Random rand = new Random();  
        public  Shape createShape(){  
            int c = rand.nextInt(3);  
            Shape s = null;  
            switch(c){  
            case 0:  
                s = new Rectangle();  
                break;  
            case 1:  
                s = new Circle();  
                break;  
            case 2:  
                s = new Triangle();  
                break;  
            }  
            return s;  
        }  
        public static void main(String[] args) {  
            ShapeDemo demo = new ShapeDemo();  
            Shape[] shapes = new Shape[10];  
            for(int i=0;i<shapes.length;i++){  
                shapes[i] = demo.createShape();  
            }  
            for(int i=0;i<shapes.length;i++){  
                shapes[i].draw();//同样的消息,不同的响应  
            }  
              
     
        }  
     

     

    Java的多态性



        面向对象编程有三个特征,即封装、继承和多态。

        封装隐藏了类的内部实现机制,从而可以在不影响使用者的前提下改变类的内部结构,同时保护了数据。

        继承是为了重用父类代码,同时为实现多态性作准备。那么什么是多态呢?

        方法的重写、重载与动态连接构成多态性。Java之所以引入多态的概念,原因之一是它在类的继承问题上和C++不同,后者允许多继承,这确实给其带来的非常强大的功能,但是复杂的继承关系也给C++开发者带来了更大的麻烦,为了规避风险,Java只允许单继承,派生类与基类间有IS-A的关系(即“猫”is a “动物”)。这样做虽然保证了继承关系的简单明了,但是势必在功能上有很大的限制,所以,Java引入了多态性的概念以弥补这点的不足,此外,抽象类和接口也是解决单继承规定限制的重要手段。同时,多态也是面向对象编程的精髓所在。

        要理解多态性,首先要知道什么是“向上转型”。

        我定义了一个子类Cat,它继承了Animal类,那么后者就是前者是父类。我可以通过

    Cat c = new Cat();
    实例化一个Cat的对象,这个不难理解。但当我这样定义时:

    Animal a = new Cat();
    这代表什么意思呢?

        很简单,它表示我定义了一个Animal类型的引用,指向新建的Cat类型的对象。由于Cat是继承自它的父类Animal,所以Animal类型的引用是可以指向Cat类型的对象的。那么这样做有什么意义呢?因为子类是对父类的一个改进和扩充,所以一般子类在功能上较父类更强大,属性较父类更独特,

    定义一个父类类型的引用指向一个子类的对象既可以使用子类强大的功能,又可以抽取父类的共性。

    所以,父类类型的引用可以调用父类中定义的所有属性和方法,而对于子类中定义而父类中没有的方法,它是无可奈何的;

    同时,父类中的一个方法只有在在父类中定义而在子类中没有重写的情况下,才可以被父类类型的引用调用;

    对于父类中定义的方法,如果子类中重写了该方法,那么父类类型的引用将会调用子类中的这个方法,这就是动态连接。



    看下面这段程序:

    class Father{
        public void func1(){
            func2();
        }
        //这是父类中的func2()方法,因为下面的子类中重写了该方法
        //所以在父类类型的引用中调用时,这个方法将不再有效
        //取而代之的是将调用子类中重写的func2()方法
        public void func2(){
            System.out.println("AAA");
        }
    }
     
    class Child extends Father{
        //func1(int i)是对func1()方法的一个重载
        //由于在父类中没有定义这个方法,所以它不能被父类类型的引用调用
        //所以在下面的main方法中child.func1(68)是不对的
        public void func1(int i){
            System.out.println("BBB");
        }
        //func2()重写了父类Father中的func2()方法
        //如果父类类型的引用中调用了func2()方法,那么必然是子类中重写的这个方法
        public void func2(){
            System.out.println("CCC");
        }
    }
     
    public class PolymorphismTest {
        public static void main(String[] args) {
            Father child = new Child();
            child.func1();//打印结果将会是什么?   
        }
    }
        上面的程序是个很典型的多态的例子。子类Child继承了父类Father,并重载了父类的func1()方法,重写了父类的func2()方法。重载后的func1(int i)和func1()不再是同一个方法,由于父类中没有func1(int i),那么,父类类型的引用child就不能调用func1(int i)方法。而子类重写了func2()方法,那么父类类型的引用child在调用该方法时将会调用子类中重写的func2()。

        那么该程序将会打印出什么样的结果呢?

        很显然,应该是“CCC”。

        对于多态,可以总结它为:


        一、使用父类类型的引用指向子类的对象;

        二、该引用只能调用父类中定义的方法和变量;

        三、如果子类中重写了父类中的一个方法,那么在调用这个方法的时候,将会调用子类中的这个方法;(动态连接、动态调用)

        四、变量不能被重写(覆盖),”重写“的概念只针对方法,如果在子类中”重写“了父类中的变量,那么在编译时会报错。

    ****************************************************************************************************************************

    多态详解(整理)2008-09-03 19:29多态是通过:
    1 接口 和 实现接口并覆盖接口中同一方法的几不同的类体现的
    2 父类 和 继承父类并覆盖父类中同一方法的几个不同子类实现的.

    一、基本概念

    多态性:发送消息给某个对象,让该对象自行决定响应何种行为。
    通过将子类对象引用赋值给超类对象引用变量来实现动态方法调用。

    java 的这种机制遵循一个原则:当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法。

    1. 如果a是类A的一个引用,那么,a可以指向类A的一个实例,或者说指向类A的一个子类。
    2. 如果a是接口A的一个引用,那么,a必须指向实现了接口A的一个类的实例。


    二、Java多态性实现机制

    SUN目前的JVM实现机制,类实例的引用就是指向一个句柄(handle)的指针,这个句柄是一对指针:
    一个指针指向一张表格,实际上这个表格也有两个指针(一个指针指向一个包含了对象的方法表,另外一个指向类对象,表明该对象所属的类型);
    另一个指针指向一块从java堆中为分配出来内存空间。

    三、总结

    1、通过将子类对象引用赋值给超类对象引用变量来实现动态方法调用。

    DerivedC c2=new DerivedC();
    BaseClass a1= c2; //BaseClass 基类,DerivedC是继承自BaseClass的子类
    a1.play(); //play()在BaseClass,DerivedC中均有定义,即子类覆写了该方法

    分析:
    * 为什么子类的类型的对象实例可以覆给超类引用?
    自动实现向上转型。通过该语句,编译器自动将子类实例向上移动,成为通用类型BaseClass;
    * a.play()将执行子类还是父类定义的方法?
    子类的。在运行时期,将根据a这个对象引用实际的类型来获取对应的方法。所以才有多态性。一个基类的对象引用,被赋予不同的子类对象引用,执行该方法时,将表现出不同的行为。

    在a1=c2的时候,仍然是存在两个句柄,a1和c2,但是a1和c2拥有同一块数据内存块和不同的函数表。

    2、不能把父类对象引用赋给子类对象引用变量

    BaseClass a2=new BaseClass();
    DerivedC c1=a2;//出错

    在java里面,向上转型是自动进行的,但是向下转型却不是,需要我们自己定义强制进行。
    c1=(DerivedC)a2; 进行强制转化,也就是向下转型.

    3、记住一个很简单又很复杂的规则,一个类型引用只能引用引用类型自身含有的方法和变量。
    你可能说这个规则不对的,因为父类引用指向子类对象的时候,最后执行的是子类的方法的。
    其实这并不矛盾,那是因为采用了后期绑定,动态运行的时候又根据型别去调用了子类的方法。而假若子类的这个方法在父类中并没有定义,则会出错。
    例如,DerivedC类在继承BaseClass中定义的函数外,还增加了几个函数(例如 myFun())

    分析:
    当你使用父类引用指向子类的时候,其实jvm已经使用了编译器产生的类型信息调整转换了。
    这里你可以这样理解,相当于把不是父类中含有的函数从虚拟函数表中设置为不可见的。注意有可能虚拟函数表中有些函数地址由于在子类中已经被改写了,所以对象虚拟函数表中虚拟函数项目地址已经被设置为子类中完成的方法体的地址了。


    4、Java与C++多态性的比较

    jvm关于多态性支持解决方法是和c++中几乎一样的,
    只是c++中编译器很多是把类型信息和虚拟函数信息都放在一个虚拟函数表中,但是利用某种技术来区别。

    Java把类型信息和函数信息分开放。Java中在继承以后,子类会重新设置自己的虚拟函数表,这个虚拟函数表中的项目有由两部分组成。从父类继承的虚拟函数和子类自己的虚拟函数。
    虚拟函数调用是经过虚拟函数表间接调用的,所以才得以实现多态的。

                Java的所有函数,除了被声明为final的,都是用后期绑定。

    四.   1个行为,不同的对象,他们具体体现出来的方式不一样,
            比如:     方法重载 overloading 以及 方法重写(覆盖)override
                      class Human{
                     void run(){输出 人在跑}
                          }
                    class Man extends Human{
                void run(){输出 男人在跑}
                      }
                     这个时候,同是跑,不同的对象,不一样(这个是方法覆盖的例子)
                    class Test{
                void out(String str){输出 str}
                 void out(int i){输出 i}
                    }
                    这个例子是方法重载,方法名相同,参数表不同

                   ok,明白了这些还不够,还用人在跑举例
                  Human ahuman=new Man();
                  这样我等于实例化了一个Man的对象,并声明了一个Human的引用,让它去指向Man这个对象
                   意思是说,把 Man这个对象当 Human看了.

                   比如去动物园,你看见了一个动物,不知道它是什么, "这是什么动物? " "这是大熊猫! "
                   这2句话,就是最好的证明,因为不知道它是大熊猫,但知道它的父类是动物,所以,
                   这个大熊猫对象,你把它当成其父类 动物看,这样子合情合理.

                  这种方式下要注意 new Man();的确实例化了Man对象,所以 ahuman.run()这个方法 输出的   是 "男人在跑 "

                   如果在子类 Man下你 写了一些它独有的方法 比如 eat(),而Human没有这个方法,

    在调用eat方法时,一定要注意 强制类型转换 ((Man)ahuman).eat(),这样才可以...

    对接口来说,情况是类似的...

    实例:

    package domatic;

    //定义超类superA
    class superA {
    int i = 100;

    void fun(int j) {
    j = i;
    System.out.println("This is superA");
    }
    }

    // 定义superA的子类subB
    class subB extends superA {
    int m = 1;

    void fun(int aa) {
    System.out.println("This is subB");
    }
    }

    // 定义superA的子类subC
    class subC extends superA {
    int n = 1;

    void fun(int cc) {
    System.out.println("This is subC");
    }
    }

    class Test {
    public static void main(String[] args) {
    superA a = new superA();
    subB b = new subB();
    subC c = new subC();
    a = b;
    a.fun(100);
    a = c;
    a.fun(200);
    }
    }
    /*
    * 上述代码中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修饰符修饰,当然也就不能被实例化了
    */
    以上大多数是以子类覆盖父类的方法实现多态.下面是另一种实现多态的方法-----------重写父类方法

    1.JAVA里没有多继承,一个类之能有一个父类。而继承的表现就是多态。一个父类可以有多个子类,而在子类里可以重写父类的方法(例如方法print()),这样每个子类里重写的代码不一样,自然表现形式就不一样。这样用父类的变量去引用不同的子类,在调用这个相同的方法print()的时候得到的结果和表现形式就不一样了,这就是多态,相同的消息(也就是调用相同的方法)会有不同的结果。举例说明:
    //父类
    public class Father{
        //父类有一个打孩子方法
        public void hitChild(){
        }
    }
    //子类1
    public class Son1 extends Father{
        //重写父类打孩子方法
        public void hitChild(){
           System.out.println("为什么打我?我做错什么了!");
        }
    }
    //子类2
    public class Son2 extends Father{
        //重写父类打孩子方法
        public void hitChild(){
           System.out.println("我知道错了,别打了!");
        }
    }
    //子类3
    public class Son3 extends Father{
        //重写父类打孩子方法
        public void hitChild(){
           System.out.println("我跑,你打不着!");
        }
    }

    //测试类
    public class Test{
        public static void main(String args[]){
           Father father;

           father = new Son1();
           father.hitChild();

           father = new Son2();
           father.hitChild();

           father = new Son3();
           father.hitChild();
        }
    }
    都调用了相同的方法,出现了不同的结果!这就是多态的表现!

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    (一)相关类

     

    class A ...{

             public String show(D obj)...{

                    return ("A and D");

             }

             public String show(A obj)...{

                    return ("A and A");

             }

    }

    class B extends A...{

             public String show(B obj)...{

                    return ("B and B");

             }

             public String show(A obj)...{

                    return ("B and A");

             }

    }

    class C extends B...{}

    class D extends B...{}

    (二)问题:以下输出结果是什么?

     

            A a1 = new A();

            A a2 = new B();

            B b = new B();

            C c = new C();

            D d = new D();

            System.out.println(a1.show(b));   ①

            System.out.println(a1.show(c));   ②

            System.out.println(a1.show(d));   ③

            System.out.println(a2.show(b));   ④

            System.out.println(a2.show(c));   ⑤

            System.out.println(a2.show(d));   ⑥

            System.out.println(b.show(b));     ⑦

            System.out.println(b.show(c));     ⑧

            System.out.println(b.show(d));     ⑨   

    (三)答案

     

                  ①   A and A

                  ②   A and A

                  ③   A and D

                  ④   B and A

                  ⑤   B and A

                  ⑥   A and D

                  ⑦   B and B

                  ⑧   B and B

                  ⑨   A and D

     

    (四)分析

     

            ①②③比较好理解,一般不会出错。④⑤就有点糊涂了,为什么输出的不是"B and B”呢?!!先来回顾一下多态性。

     

            运行时多态性是面向对象程序设计代码重用的一个最强大机制,动态性的概念也可以被说成“一个接口,多个方法”。Java实现运行时多态性的基础是动态方法调度,它是一种在运行时而不是在编译期调用重载方法的机制。

     

            方法的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写(Overriding)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被“屏蔽”了。如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。Overloaded的方法是可以改变返回值的类型。方法的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被“屏蔽”了。如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。Overloaded的方法是可以改变返回值的类型。

     

            当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法。 (但是如果强制把超类转换成子类的话,就可以调用子类中新添加而超类没有的方法了。)

     

            好了,先温习到这里,言归正传!实际上这里涉及方法调用的优先问题 ,优先级由高到低依次为:this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O)。让我们来看看它是怎么工作的。

     

            比如④,a2.show(b),a2是一个引用变量,类型为A,则this为a2,b是B的一个实例,于是它到类A里面找show(B obj)方法,没有找到,于是到A的super(超类)找,而A没有超类,因此转到第三优先级this.show((super)O),this仍然是a2,这里O为B,(super)O即(super)B即A,因此它到类A里面找show(A obj)的方法,类A有这个方法,但是由于a2引用的是类B的一个对象,B覆盖了A的show(A obj)方法,因此最终锁定到类B的show(A obj),输出为"B and A”。

     

            再比如⑧,b.show(c),b是一个引用变量,类型为B,则this为b,c是C的一个实例,于是它到类B找show(C obj)方法,没有找到,转而到B的超类A里面找,A里面也没有,因此也转到第三优先级this.show((super)O),this为b,O为C,(super)O即(super)C即B,因此它到B里面找show(B obj)方法,找到了,由于b引用的是类B的一个对象,因此直接锁定到类B的show(B obj),输出为"B and B”。

     

            按照上面的方法,可以正确得到其他的结果。

     

            问题还要继续,现在我们再来看上面的分析过程是怎么体现出蓝色字体那句话的内涵的。它说:当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法。还是拿a2.show(b)来说吧。

     

     

            a2是一个引用变量,类型为A,它引用的是B的一个对象,因此这句话的意思是由B来决定调用的是哪个方法。因此应该调用B的show(B obj)从而输出"B and B”才对。但是为什么跟前面的分析得到的结果不相符呢?!问题在于我们不要忽略了蓝色字体的后半部分,那里特别指明:这个被调用的方法必须是在超类中定义过的,也就是被子类覆盖的方法。B里面的show(B obj)在超类A中有定义吗?没有!那就更谈不上被覆盖了。实际上这句话隐藏了一条信息:它仍然是按照方法调用的优先级来确定的。它在类A中找到了show(A obj),如果子类B没有覆盖show(A obj)方法,那么它就调用A的show(A obj)(由于B继承A,虽然没有覆盖这个方法,但从超类A那里继承了这个方法,从某种意义上说,还是由B确定调用的方法,只是方法是在A中实现而已);现在子类B覆盖了show(A obj),因此它最终锁定到B的show(A obj)。这就是那句话的意义所在。

     

     

    展开全文
  • 对象多态性主要应用在抽象类和接口上。 对象的多态性主要分为以下两种类型: 向上转型:子类对象——>父类对象。对于向上转型,程序会自动完成,格式:  对象向上转型:父类 父类对象 = 子类实例; 向下...
  • 多态性

    千次阅读 2013-09-09 14:24:53
    面向对象程序设计中的多态性: 多态性(polymorphism)是面向对象编程的基本特征之... 从系统实现角度来看,多态性分为两类:静态多态性和动态多态性。  静态多态性:在程序编译时系统就能决定调用哪个函数,因此静态函
  • C++的多态性

    千次阅读 2019-06-23 20:07:54
    C++的多态性主要是重载和虚函数。 一: 先是重载,分为函数重载和运算符重载。 函数重载:虽然函数名相同,但是函数内容不同,靠参数不同来区分。 例子: 对 f() 进行重载: #include<iostream> #include<...
  • java多态性

    千次阅读 2019-06-10 16:24:57
    1.子类对象多态性,父类的引用指向子类对象 2.虚拟方法调用:通过父类的引用指向子类的对象实体,当调用方法时,实际上执行的是子类重写父类的方法 多态性的前提: 1,要有类的继承性. 2,要有子类对父类的方法...
  • 1. 什么是多态性 1.0多态的简要介绍:多态中的态为形态的意思,在面向对象编程中是指向不同的对象发送同一个消息,不同的对象在...然后按照其特性来又分为静态多态性和动态多态性这两种,那么这两种又有什么区别呢?...
  • C++多态性

    万次阅读 2016-02-16 21:26:25
    1.1多态性(polymorphism)是面向对象程序设计的一个重要特征。 1.2从系统实现的角度看,多态性分两类:静态多态性与动态多态性。 静态多态性是通过函数重载(运算符重载也是函数重载)来实现的。它又称为编译时多态。...
  • 面向对象中的多态性

    千次阅读 2006-12-09 19:59:00
     多态分为两种:通用的多态(universal)和特定的多态(ad hoc)。前者用来系统地刻画语义上相关的一组类型。;后者用来刻画语义上无关联的类型间的关系。通用的多态又分为参数多态(parametric)和包含多态...
  • 多态性有哪些,怎么实现

    千次阅读 2018-07-23 21:20:06
    C++的多态性:在基类的函数前加上virtual关键字,在派生类中重写该函数,指相同的对象收到不同的消息或者不同的对象收到相同的消息时产生的不同的实现动作。如果对象类型是派生类,就调用派生类的函数;如果对象类型...
  • 网友回答:网友:daizh面向对象程序设计语言c++中的多态性 蓝雯飞 c++是以c语言为基础,支持数据抽象和面向对象的程序设计语言。c++对c语言的扩充部分汲取了许多著名语言中最优秀的特征,如从algo168中吸取了操作符...
  • 面向对象的系统常常要求一组具有相同基本语义的方法能在同一接口下为不同的对象服务这就是所谓的多态性polymorphism 所谓多态性是指发出同样的消息被不同类型的对象接收时导致完全不同的行为即指相同的函数名对应...
  • 类的多态性的概念

    千次阅读 2013-08-27 16:32:10
    多态性(polymorphism)是面向对象程序设计的一个重要特征。利用多态性可以设计和实现一个易于扩展的系统。 在C++程序设计中,多态性是指具有不同功能的函数可以用同一个函数名,这样就可以用一个函数名调用不同内容...
  • C#中的多态性

    千次阅读 2020-01-30 19:24:10
    多态是指一个行为具有多个不同表现形式的能力,在C#中通过多态性的检测时机可以分为静态多态性和动态多态性静态多态性:函数重载和运算符重载 动态多态性:抽象方法、重写方法、隐藏方法 二:函数重载(overlode) ...
  • 面向对象技术第一讲 多态性

    千次阅读 2004-12-03 07:52:00
    面向对象技术第一讲 多态性一﹑什么是多态?为什么要支持多态?多态是一种普遍存在的现象,如water的三种形态:冰﹑水﹑汽,又如算术运算1+1, 1+0.5, 1/2+0.5等。多态性用一句经典的英文来解释就是:a value can ...
  • C++多态性及虚函数

    千次阅读 2013-08-20 13:43:55
    多态性分为:静态多态性和动态多态性 静态多态性(编译多态性):通过重载实现(包括函数的重载、运算符的重载)。 动态多态性(运行多态性):通过虚函数实现。 虚函数 虚函数真正作用:突破了无法通过基类指针...
  • 面向对象(四)多态以及多态性

    千次阅读 2018-04-16 15:11:00
    多态性分为静态多态性和动态多态性   静态多态性:如任何类型都可以用运算符+进行运算  动态多态性:如下 peo= People() dog = Dog() pig = Pig() # peo、dog、pig都是动物,只要是动物肯定有talk方法 #...
  • c++多态性

    2008-05-03 09:52:00
    在c++系统中,多态性是指具有不同功能的函数可以用同一个函数名,这样可以用同一个...它分为:静态多态性和动态多态性;以前学过的函数重载很运算符重载实现的多态性属于静态多态性,动态多态性是通过虚函数来实现的。
  • 三.Java的多态性

    千次阅读 2013-03-14 11:52:33
    3.1 多态性的含义 通过类型转换,把一个对象当作它的基类对象对待。  从相同的基类派生出来的多个派生类可被当作同一个类型对待,可对这些不同的类型进行同样的处理。 测试例子: public class Game { ...
  • c++的多态性分为静态多态性与动态多态性。比如函数重载,一个函数名给出不同的参数,实现功能上大体相同细节上因情况而定的多态性,这种多态性是在编译的时候就确定了的,称为静态多态性;一种是动态多态性,是子类...
  • 什么是类的多态性

    千次阅读 2013-11-11 22:57:55
    C#多态性分为两种,一种是编译时的多态性,一种是运行时的多态性。 ◆编译时的多态性:编译时的多态性是通过重载来实现的。对于非虚的成员来说,系统在编译时,根据传递的参数、返回的类型等信息决定实现何种操作。...
  • C#多态性基础实现

    千次阅读 热门讨论 2014-02-09 17:45:35
    多态分为两种情况,一种是编译的时候的多态性,一种是运行时的多态性。 编译时的多态性:编译时的多态性是通过重载来实现的。对于非虚的成员来说,系统在编译时,根据传递的参数、返回的类型等信息决定实现何种操作...
  • C++多态性的理解

    千次阅读 2017-04-15 20:30:05
    面向对象多态性可以分为4类: 专用多态: (1)重载多态:普通函数以及成员函数的重载。 (2)强制多态:将一个变量的类型加以变化。 通用多态: (3)包含多态:研究类族中定义于不同类中的同名成员...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 56,986
精华内容 22,794
关键字:

对象多态性主要分为