精华内容
下载资源
问答
  • C++多态实现机制

    2017-07-17 14:15:22
    多态分为两种,静态多态和动态多态。静态多态也称编译时多态,主要包括模板和重载。而动态多态则是通过类的继承和虚函数来实现,当基类和子类拥有同名同参同返回...模板就是实现代码重用机制的一种工具,它可以实现类型

    多态分为两种,静态多态和动态多态。静态多态也称编译时多态,主要包括模板和重载。而动态多态则是通过类的继承和虚函数来实现,当基类和子类拥有同名同参同返回的方法,且该方法声明为虚方法,当基类对象,指针,引用指向的是派生类的对象的时候,基类对象,指针,引用在调用基类的虚函数,实际上调用的是派生类函数。这就是动态多态。

    静态多态:

    1.   模板:
    模板就是实现代码重用机制的一种工具,它可以实现类型参数化,即把类型定义为参数, 从而实现了真正的代码可重用性。模版可以分为两类,一个是函数模版,另外一个是类模版。
    2.   重载

    在相同的范围函数名字相同,参数不同的函数(重写不再同一个之中,重写的参数可以相同)

    #include <iostream>
    using namespace std;
    /*
     *模板化编程 
     */ 
    template <typename T1, typename T2>
    int fun(T1 t1, T2 t2){
    	return t1+t2;
    }
    /*
     *函数重载 
     */ 
    int foofun(){}
    int foofun(int){}
    int foofun(int , float){}
    int foofun(int , float ,double){}
    
    int main(int argc, char *argv[])
    {
        fun(1, 2);
        fun(1, 1.1);
        foofun();
        foofun(1);
        foofun(1, 1.1);
        foofun(1, 1.1, 1.11);
        return 0;
    }

    动态多态:

    声明一个类时,如果类中有虚方法,则自动在类中增加一个虚函数指针,该指针指向的是一个虚函数表,虚函数表中存着每个虚函数真正对应的函数地址。动态多态采用一种延迟绑定技术。

    普通的函数调用,在编译期间就已经确定了调用的函数的地址,所以无论怎样调用,总是那个函数,但是拥有虚函数的类,在调用虚函数时,首先去查虚函数表,然后在确定调用的是哪一个函数,所以,调用的函数是在运行时才会确定的。

    详细去看:http://blog.csdn.net/mingwanganyu/article/details/70833745(我的博客:虚函数与纯虚函数)


    展开全文
  • java - 多态实现机制

    2019-10-03 05:04:24
    Java提供了编译时多态和运行时多态两种多态机制。前者是通过方法重载实现的,后者是通过方法的覆盖实现的。  在方法覆盖中,子类可以覆盖父类的方法,因此同类的方法会在父类与子类中有着不同的表现形式。  在...

    Java提供了编译时多态和运行时多态两种多态机制。前者是通过方法重载实现的,后者是通过方法的覆盖实现的。

      在方法覆盖中,子类可以覆盖父类的方法,因此同类的方法会在父类与子类中有着不同的表现形式。

      在Java语言中,基类的引用变量不仅可以指向基类的实例对象,也可以指向其子类中的实例对象。同样,接口中的引用变量也可以指向其实现类的实例对象。而程序调用的方法在运行时期才动态绑定(绑定是指将一个方法调用和一个方法主体联系在一起),绑定的是引用变量所指向的具体实例对象的方法,也就是内存中正在运行的那个对象的方法,而不是引用变量的类型中定义的方法。通过这种动态绑定实现了多态。由于只有在运行时才能确定调用哪个方法,因此通过方法覆盖实现的多态也可以被称为运行时多态。

    转载于:https://www.cnblogs.com/20158424-hxlz/p/10313176.html

    展开全文
  • Java 多态实现机制 http://my.oschina.net/onlytwo/blog/52222 是父类或接口定义的引用变量可以指向子类或实现类的实例对象,而程序调用的方法在运行期才动态绑定,就是引用变量所指向的具体实现对象的方法,也...

    Java 多态的实现机制
    http://my.oschina.net/onlytwo/blog/52222

    是父类或接口定义的引用变量可以指向子类或实现类的实例对象,而程序调用的方法在运行期才动态绑定,就是引用变量所指向的具体实现对象的方法,也就是内存里正在运行的那个对象的方法,而不是引用变量的类型中定义的方法。

    http://blog.hesey.net/2010/12/significance-and-implementation-of-polymorphism.html

    浅谈多态机制的意义及实现
    在面向对象编程(Object-Oriented Programming, OOP)中,多态机制无疑是其最具特色的功能,甚至可以说,不运用多态的编程不能称之为OOP。这也是为什么有人说,使用面向对象语言的编程和面向对象的编程是两码事。

    多态并没有一个严格的定义,维基百科上给它下的定义比较宽松:

    Subtype polymorphism, almost universally called just polymorphism in the context of object-oriented programming, is the ability of one type, A, to appear as and be used like another type, B.

    一、子类型和子类
    这里我想先提一下子类型(Subtype)这个词和子类(Subclass)的区别,简单地说,只要是A类运用了extends关键字实现了对B类的继承,那么我们就可以说Class A是Class B的子类,子类是一个语法层面上的词,只要满足继承的语法,就存在子类关系。

    子类型比子类有更严格的要求,它不仅要求有继承的语法,同时要求如果存在子类对父类方法的改写(override),那么改写的内容必须符合父类原本的语义,其被调用后的作用应该和父类实现的效果方向一致。

    对二者的对比是想强调一点:只有保证子类都是子类型,多态才有意义。

    二、多态的机制
    本质上多态分两种:

    1、编译时多态(又称静态多态)

    2、运行时多态(又称动态多态)

    重载(overload)就是编译时多态的一个例子,编译时多态在编译时就已经确定,运行时运行的时候调用的是确定的方法。

    我们通常所说的多态指的都是运行时多态,也就是编译时不确定究竟调用哪个具体方法,一直延迟到运行时才能确定。这也是为什么有时候多态方法又被称为延迟方法的原因。

    在维基百科中多态的行为被描述为:

    The primary usage of polymorphism in industry (object-oriented programming theory) is the ability of objects belonging to different types to respond to method, field, or property calls of the same name, each one according to an appropriate type-specific behavior.

    下面简要介绍一下运行时多态(以下简称多态)的机制。

    多态通常有两种实现方法:

    1、子类继承父类(extends)

    2、类实现接口(implements)

    无论是哪种方法,其核心之处就在于对父类方法的改写或对接口方法的实现,以取得在运行时不同的执行效果。

    要使用多态,在声明对象时就应该遵循一条法则:声明的总是父类类型或接口类型,创建的是实际类型。举例来说,假设我们要创建一个ArrayList对象,声明就应该采用这样的语句:

    List list =newArrayList();
    而不是

    ArrayList list =newArrayList();
    在定义方法参数时也通常总是应该优先使用父类类型或接口类型,例如某方法应该写成:

    publicvoid doSomething(List list);
    而不是

    publicvoid doSomething(ArrayList list);
    这样声明最大的好处在于结构的灵活性:假如某一天我认为ArrayList的特性无法满足我的要求,我希望能够用LinkedList来代替它,那么只需要在对象创建的地方把new ArrayList()改为new LinkedList即可,其它代码一概不用改动。

    The programmer (and the program) does not have to know the exact type of the object in advance, and so the exact behavior is determined at run-time (this is called late binding or dynamic binding).

    虚拟机会在执行程序时动态调用实际类的方法,它会通过一种名为动态绑定(又称延迟绑定)的机制自动实现,这个过程对程序员来说是透明的。

    三、多态的用途
    多态最大的用途我认为在于对设计和架构的复用,更进一步来说,《设计模式》中提倡的针对接口编程而不是针对实现编程就是充分利用多态的典型例子。定义功能和组件时定义接口,实现可以留到之后的流程中。同时一个接口可以有多个实现,甚至于完全可以在一个设计中同时使用一个接口的多种实现(例如针对ArrayList和LinkedList不同的特性决定究竟采用哪种实现)。

    四、多态的实现
    下面从虚拟机运行时的角度来简要介绍多态的实现原理,这里以Java虚拟机(Java Virtual Machine, JVM)规范的实现为例。

    在JVM执行Java字节码时,类型信息被存放在方法区中,通常为了优化对象调用方法的速度,方法区的类型信息中增加一个指针,该指针指向一张记录该类方法入口的表(称为方法表),表中的每一项都是指向相应方法的指针。

    方法表的构造如下:

    由于Java的单继承机制,一个类只能继承一个父类,而所有的类又都继承自Object类。方法表中最先存放的是Object类的方法,接下来是该类的父类的方法,最后是该类本身的方法。这里关键的地方在于,如果子类改写了父类的方法,那么子类和父类的那些同名方法共享一个方法表项,都被认作是父类的方法。

    注意这里只有非私有的实例方法才会出现,并且静态方法也不会出现在这里,原因很容易理解:静态方法跟对象无关,可以将方法地址直接引用,而不像实例方法需要间接引用。

    更深入地讲,静态方法是由虚拟机指令invokestatic调用的,私有方法和构造函数则是由invokespecial指令调用,只有被invokevirtual和invokeinterface指令调用的方法才会在方法表中出现。

    由于以上方法的排列特性(Object——父类——子类),使得方法表的偏移量总是固定的。例如,对于任何类来说,其方法表中equals方法的偏移量总是一个定值,所有继承某父类的子类的方法表中,其父类所定义的方法的偏移量也总是一个定值。

    前面说过,方法表中的表项都是指向该类对应方法的指针,这里就开始了多态的实现:

    假设Class A是Class B的子类,并且A改写了B的方法method(),那么在B的方法表中,method方法的指针指向的就是B的method方法入口。

    而对于A来说,它的方法表中的method方法则会指向其自身的method方法而非其父类的(这在类加载器载入该类时已经保证,同时JVM会保证总是能从对象引用指向正确的类型信息)。

    结合方法指针偏移量是固定的以及指针总是指向实际类的方法域,我们不难发现多态的机制就在这里:

    在调用方法时,实际上必须首先完成实例方法的符号引用解析,结果是该符号引用被解析为方法表的偏移量。虚拟机通过对象引用得到方法区中类型信息的入口,查询类的方法表,当将子类对象声明为父类类型时,形式上调用的是父类方法,此时虚拟机会从实际类的方法表(虽然声明的是父类,但是实际上这里的类型信息中存放的是子类的信息)中查找该方法名对应的指针(这里用“查找”实际上是不合适的,前面提到过,方法的偏移量是固定的,所以只需根据偏移量就能获得指针),进而就能指向实际类的方法了。

    我们的故事还没有结束,事实上上面的过程仅仅是利用继承实现多态的内部机制,多态的另外一种实现方式:实现接口相比而言就更加复杂,原因在于,Java的单继承保证了类的线性关系,而接口可以同时实现多个,这样光凭偏移量就很难准确获得方法的指针。所以在JVM中,多态的实例方法调用实际上有两种指令:

    invokevirtual指令用于调用声明为类的方法;

    invokeinterface指令用于调用声明为接口的方法。

    当使用invokeinterface指令调用方法时,就不能采用固定偏移量的办法,只能老老实实挨个找了(当然实际实现并不一定如此,JVM规范并没有规定究竟如何实现这种查找,不同的JVM实现可以有不同的优化算法来提高搜索效率)。我们不难看出,在性能上,调用接口引用的方法通常总是比调用类的引用的方法要慢。这也告诉我们,在类和接口之间优先选择接口作为设计并不总是正确的,当然设计问题不在本文探讨的范围之内,但显然具体问题具体分析仍然不失为更好的选择。

    个人见解:多态机制包括静态多态(编译时多态)和动态多态(运行时多态),静态多态比如说重载,动态多态是在编译时不能确定调用哪个方法,得在运行时确定。动态多态的实现方法包括子类继承父类和类实现接口。当多个子类上转型(不知道这么说对不)时,对象掉用的是相应子类的方法,这种实现是与JVM有关的。

    展开全文
  • C++中多态实现机制

    千次阅读 2012-08-16 00:03:23
    多态是一种不同的对象以单独的方式作用于相同消息的能力,这个概念是从自然语言中引进的。例如,动词“关闭”应用到不同的事务上其意思是不同的。关门,关闭银行账号或关闭一个程序的窗口都是不同的行为;其实际的...


    http://hi.baidu.com/zhangcy8511/blog/item/d554b2c2d41ac129e5dd3bfd.html


    多态是一种不同的对象以单独的方式作用于相同消息的能力,这个概念是从自然语言中引进的。例如,动词“关闭”应用到不同的事务上其意思是不同的。关门,关闭银行账号或关闭一个程序的窗口都是不同的行为;其实际的意义取决于该动作所作用的对象。
    大多数面向对象语言的多态特性都仅以虚拟函数的形式来实现,但C++除了一般的虚拟函数形式之外,还多了两种静态的(即编译时的)多态机制:

    1、操作符重载:例如,对整型和串对象应用 += 操作符时,每个对象都是以单独的方式各自进行解释。显然,潜在的 += 实现在每种类型中是不同的。但是从直观上看,我们可以预期结果是什么。

    2、模板:例如,当接受到相同的消息时,整型vector对象和串vector对象对消息反映是不同的,我们以关闭行为为例:

    vector < int > vi;   vector < string > names; 

    string name("VC知识库");

    vi.push_back( 5 ); // 在 vector 尾部添加整型
    names.push_back (name); // 添加串和添加整型体现差别的潜在的操作

    静态的多态机制不会导致与虚拟函数相关的运行时开。此外,操作符重载和模板两者是通用算法最基本的东西,在STL中体现得尤为突出。

    那么接下来我们说说以虚函数形式多态:

    通常都有以重载、覆盖、隐藏来三中方式,三种方式的区别大家应该要很深入的了解,这里就不多说了。

    C++的多态性搞混淆,下面我从两方面为大家解说:

          1、 编译的角度

    C++编译器在编译的时候,要确定每个对象调用的函数的地址,这称为早期绑定(early binding)。

    2、 内存模型的角度

    为了确定对象调用的函数的地址,就要使用迟绑定(late binding)技术。当编译器使用迟绑定时,就会在运行时再去确定对象的类型以及正确的调用函数。而要让编译器采用迟绑定,就要在基类中声明函数时使用virtual关键字(注意,这是必须的,很多开发人员就是因为没有使用虚函数而写出很多错误的例子),这样的函数我们称为虚函数。一旦某个函数在基类中声明为virtual,那么在所有的派生类中该函数都是virtual,而不需要再显式地声明为virtual。

    那么如何定位虚表呢?编译器另外还为每个类的对象提供了一个虚表指针(即vptr),这个指针指向了对象所属类的虚表。在程序运行时,根据对象的类型去初始化vptr,从而让vptr正确的指向所属类的虚表,从而在调用虚函数时,就能够找到正确的函数。

    正是由于每个对象调用的虚函数都是通过虚表指针来索引的,也就决定了虚表指针的正确初始化是非常重要的。换句话说,在虚表指针没有正确初始化之前,我们不能够去调用虚函数。那么虚表指针在什么时候,或者说在什么地方初始化呢?

    答案是在构造函数中进行虚表的创建和虚表指针的初始化。还记得构造函数的调用顺序吗,在构造子类对象时,要先调用父类的构造函数,此时编译器只“看到了”父类,并不知道后面是否后还有继承者,它初始化父类对象的虚表指针,该虚表指针指向父类的虚表。当执行子类的构造函数时,子类对象的虚表指针被初始化,指向自身的虚表。

    要注意:对于虚函数调用来说,每一个对象内部都有一个虚表指针,该虚表指针被初始化为本类的虚表。所以在程序中,不管你的对象类型如何转换,但该对象内部的虚表指针是固定的,所以呢,才能实现动态的对象函数调用,这就是C++多态性实现的原理。

    总结(基类有虚函数):

    1、 每一个类都有虚表。

    2、 虚表可以继承,如果子类没有重写虚函数,那么子类虚表中仍然会有该函数的地址,只不过这个地址指向的是基类的虚函数实现。如果基类3个虚函数,那么基类的虚表中就有三项(虚函数地址),派生类也会有虚表,至少有三项,如果重写了相应的虚函数,那么虚表中的地址就会改变,指向自身的虚函数实现。如果派生类有自己的虚函数,那么虚表中就会添加该项。

    3、 派生类的虚表中虚函数地址的排列顺序和基类的虚表中虚函数地址排列顺序相同。


    总结:

    百度电话面试时,面试过我这个问题,这个机制我之前是有过了解的,但平时主要用的是C,因此记忆有些模糊了,但是仍然答对了主要的部分,但是面试官一直要问到底,非要我把我完整的机制的说出来不行;除了这个问题之外,还问我过一个感觉最后成就的一件事,我就把我花一个周定位的问题说了一下,对于我负责的程序,是十分要求效率的,调用频繁的函数都不会有指针的非空判断,但是流程出了问题,那函数就会异常,最终这个问题,我分析异常栈,分析代码流程,最终花了2个周的时间定位了这个问题,面试官却一直纠结于说,函数没有判断入参指针是个Bug,不能把这个Bug当作一个有成就的事情;这确实让我很无语,也寄予百度一些希望,即使是电话面试,也要派一个真正的面试官吧。

    展开全文
  • 深入总结Java中多态实现机制

    千次阅读 2009-06-24 11:05:00
    深入总结Java中多态实现机制 一、多态概述:面向对象程序设计语言中,多态是继数据抽象和继承之后的第三种基本特征。“封装”通过合并特征和行为来创建新的数据类型。“实现隐藏”则通过将细节“私有化”把接口和...
  • 最近对多态实现机制比较感兴趣,本文从C++内存模型角度去看待多态实现机制。实例如下: #include #include #include using namespace std; class Animal {  public:  Animal(int a = 1, int b = 2)  {
  • c++多态实现机制

    2021-05-25 11:49:28
    c++多态实现机制 1、 什么是多态? 顾名思义就是同一事物在不同场景的不同形态。 静态多态是在编译期间编译器可以根据实参来确定的,主要体现在两个方面函数重载和泛型。 函数重载 int Add(int left, int ...
  • 一种错误的观点是:c++与java多态性的实现机制不同,但它们的表现形式应该相同。以下我将举出两个例子(请耐心看)。class Super { public Super() { init(); } protected void init() { System.out.print(...
  • 基础> 多态实现机制

    千次阅读 2014-07-21 11:35:38
    1 什么是多态? 多态性可以简单的概括为“1个接口,多种方法”,在程序运行的过程中才决定调用的机制 ...2 实现机制 举一个例子: #include class animal { public: void sleep() { cout } void breathe() { cout } };
  • 多态实现机制

    千次阅读 2018-08-28 10:47:35
    多态是C++编程时的一种特性,多态性即是对一个接口的多种实现多态可以分为静多态和动多态。所谓静多态就好比函数重载、模板,静多态是在函数编译阶段就决定调用机制,即在编译连接阶段就将函数的入口地址给出。而...
  • Java多态实现机制

    2020-02-07 10:05:48
    Java提供了编译时多态和运行时多态两种多态机制。前者是通过方法重载实现的,后者是通过方法的覆盖实现的。  在方法覆盖中,子类可以覆盖父类的方法,因此同类的方法会在父类与子类中有着不同的表现形式。 ...
  • 详解多态实现机制

    2020-11-02 16:30:10
    多态的三种表现形式 多态: 就是多种形态,在完成某个行为时,不同对象完成会产生...多态实现机制 因为静多态只有在运行阶段才会确定函数的调用,所以我们需要在运行阶段获取到函数的入口地址才能实现多态。但是在程
  • 什么是多态实现多态机制是什么?

    千次阅读 多人点赞 2018-10-30 22:13:00
    接口的多种不同实现方式即为多态。 多态性是允许你将父对象设置成为一个或更多的他的子对象相等的技术。 我们在程序中定义的引用变量所指向的具体类型和通过该引用变量的方法调用在编程的时候并不确定,当处于...
  • java实现多态机制

    2011-03-16 09:43:00
    java实现多态机制
  • 所谓多态:定义时的类型和运行时的类型不一样,此时就成为多态多态的概念是应用于Java和C#这一类强类型语言中,而Python崇尚“鸭子类型”。 鸭子类型:虽然我想要一只"鸭子",但是你给了我一只鸟。 但是只要这只...
  • 多态实现机制

    2019-07-18 10:42:02
    参考:...一、Java多态实现机制是什么? 答:开门、开窗户、开电视。这里的“开”就是多态。 多态性可以简单的概括为“一个接口,多种方法”。在程序运行的过程中才决定调用哪个函数。多态性...
  • Java 多态实现机制

    2019-11-27 18:51:08
    是父类或接口定义的引用变量可以指向子类或实现类的实例对象,而程序调用的方法在运行期才动态绑定,就是引用变量所指向的具体实现对象的方法,也就是内存里正在运行的那个对象的方法,而不是引用变量的类型中定义的...
  • java中实现多态机制

    2016-02-23 11:18:13
    java中实现多态机制靠的是父类或者接口定义的引用变量可以指向子类或者具体的实现类的实例对象,而程序调的方法在运行期才动态绑定,就是引用变量所指向的具体实例对象的方法,也就是内存里正在运行的那个对象的...
  • java中实现多态机制是什么?

    千次阅读 2017-11-16 09:29:23
    封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据。对外界而已它的内部细节是隐藏的,暴露给外界的只是它的访问方法。 继承是为了重用父类代码。两个类若存在IS-A的关系...
  • C++多态实现机制

    2011-09-12 16:36:07
    在面向对象语言中,接口的多种不同实现方式即为多态。引用Charlie Calverts对多态的描述——多态性是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当
  • Java多态实现机制是父类或接口定义的引用变量可以指向子类或实现类的实例对象,而程序调用的方法在运行期才动态绑定,就是引用变量所指向的具体实现对象的方法,也就是内存里正在运行的那个对象的方法,而不是引用...
  • Java 中实现多态机制是什么? 答:重载(overload)和重写(override) 如果一个子类继承了一个父类,子类中拥有和父类相同方法名称,返回值,参数类型的话,就是重写,会执行子类中的方法。 如果一个类中定义了多个...
  • C++ 多态机制实现

    2017-03-26 16:09:48
    C++ 多态机制实现 compiler implement late binding mechanism 迟绑定是如何实现的(How C++ implements late binding)关键字virtual告诉编译器不应该执行早期绑定,相反的,应该自动的安装所有必要的机制去执行迟...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 84,568
精华内容 33,827
关键字:

不同类型多态实现的机制