精华内容
下载资源
问答
  • C++之多态性

    万次阅读 多人点赞 2019-06-05 00:25:31
    1.初探多态性 在面向对象方法中,所谓多态性就是不同对象收到相同消息,产生不同的行为。在C++程序设计中,多态性是指用一个名字定义不同的函数,这些函数执行不同但又类似的操作,这样就可以用同一个函数名调用不同...

    1.初探多态性

    在面向对象方法中,所谓多态性就是不同对象收到相同消息,产生不同的行为。在C++程序设计中,多态性是指用一个名字定义不同的函数,这些函数执行不同但又类似的操作,这样就可以用同一个函数名调用不同内容的函数。换言之,可以用同样的接口访问功能不同的函数,从而实现“一个接口,多种方法”。

    事实上,在程序设计中经常会使用到多态性。最简单的例子就是运算符了,例如我们使用运算符+,就可以实现整型数、浮点数、双精度类型之间的加法运算,这三种类型的加法操作其实是互不相同的,是由不同内容的函数实现的。这个例子就是使用了多态的特征。

    在C++中,多态性的实现和联编(也称绑定)这一概念有关。一个源程序经过编译、链接,成为可执行文件的过程是把可执行代码联编(或称装配)在一起的过程。其中在运行之前就完成的联编成为静态联编(前期联编);而在程序运行之时才完成的联编叫动态联编(后期联编)

    静态联编支持的多态性称为编译时多态性(静态多态性)。在C++中,编译时多态性是通过函数重载和模板实现的。利用函数重载机制,在调用同名函数时,编译系统会根据实参的具体情况确定索要调用的是哪个函数。

    动态联编所支持的多态性称为运行时多态(动态多态)。在C++中,运行时多态性是通过虚函数来实现的。

    再举一个通俗易懂的例子:比如买票这个行为,普通人买是全价;学生买是半价票等。

    2.多态的定义和实现

    2.1 多态定义构成条件

    多态是在不同继承关系的类对象,去调用同一函数,产生了不同的行为。比如Student继承了Person.Person买票就是全价,而Student买票就是半价。

    那么在继承中要构成多态还需要两个条件:
    a. 调用函数的对象必须是指针或者引用
    b. 被调用的函数必须是虚函数,且完成了虚函数的重写。

    什么是虚函数?
    虚函数:在类的成员函数前加virtual关键字。

    class Person
    {
    public:
    	virtual void BuyTicket()
    	{
    		cout << "买票-全价" << endl;
    	}
    };
    

    什么是虚函数的重写?
    虚函数的重写:派生类中有一个跟基类的完全相同的虚函数,我们就称子类的虚函数重写了基类的虚函数。“完全相同”是指:函数名、参数、返回值都相同。另外,虚函数的重写也叫做虚函数的覆盖。

    示例代码:

    #include <iostream>
    #include <stdlib.h>
    
    using namespace std;
    
    class Person
    {
    public:
    	virtual void BuyTicket()
    	{
    		cout << "买票-全价" << endl;
    	}
    };
    
    class Student : public Person
    {
    public:
    	virtual void BuyTicket(){
    		cout << "买票-半价" << endl;
    	}
    };
    
    void Func(Person& p)
    {
    	p.BuyTicket();
    }
    
    int main()
    {
    	Person ps;
    	Student st;
    
    	Func(ps);
    	Func(st);
    
    	system("pause");
    	return 0;
    }
    

    不规范的重写行为

    在派生类中重写的成员函数可以不加virtual关键字,也是构成重写,因为继承后基类的虚函数被继承下来,在派生类中依旧保持虚函数的属性,我们只是重写了它。这是非常不规范的,在平时尽量不要这样使用。

    注意:若子类中的函数有virtual修饰,而父类中没有,则会构成函数隐藏。

    基类中的析构函数如果是虚函数,那么派生类的析构函数就重写了基类的析构函数。这里他们的函数名不相同,看起来违背了重写的规则,其实不然,这里可以理解为编译器对析构函数的名称做了特殊处理,编译后析构函数的名称统一处理成destructor,这也说明基类的析构函数最好写成虚函数

    这里贴一个链接,专门解释了为什么基类的析构函数最好写成虚函数:https://blog.csdn.net/komtao520/article/details/82424468

    接口继承与实现继承
    普通函数的继承是一种实现继承,派生类继承了基类函数,可以使用函数,继承的是函数的实现。虚函数的继承是一种接口继承,派生类继承的是基类虚函数的接口,目的是为了重写,达成多态,继承的是接口。所以,如果不实现多态,不要把函数定义成虚函数。

    3. 抽象类

    在虚函数的后面写上 = 0,则这个函数为纯虚函数。包含纯虚函数的类叫做抽象类(也叫接口类),抽象类不能实例化出对象。派生类继承后也不能实例化出对象。只有重写纯虚函数,派生类才能实例化出对象。纯虚函数规范了派生类必须重写,另外纯虚函数更体现了接口继承。

    示例代码:

    #include<iostream>
    #include <stdlib.h>
    using namespace std;
    
    class Car
    {
    public:
    	//纯虚函数
    	virtual void Drive() = 0;
    };
    
    class Benz :public Car
    {
    public:
    	virtual void Drive(){
    		cout << "Benz-舒适" << endl;
    	}
    };
    
    class BMW :public Car
    {
    public:
    	virtual void Drive(){
    		cout << "BMW-操控" << endl;
    	}
    };
    
    void Test()
    {
    	Car* pBenz = new Benz;
    	pBenz->Drive();
    
    	Car* pBMW = new BMW;
    	pBMW->Drive();
    }
    
    int main()
    {
    	Test();
    	system("pause");
    	return 0;
    }
    

    结果: Benz-舒适
    BMW-操控

    4. 多态的原理

    4.1 虚函数表

    //计算sizeof(b)为多少???
    #include<iostream>
    #include <stdlib.h>
    using namespace std;
    
    class Base
    {
    public:
    	virtual void Fun1(){
    		cout << "Func1()" << endl;
    	}
    private:
    	int _b = 1;
    };
    
    int main()
    {
    	Base b;
    	cout << "sizeof(b):" << sizeof(b) << endl;
    	system("pause");
    	return 0;
    }
    

    在这里插入图片描述
    通过测试我们发现sizeof(Base)大小为8字节。除了_b成员,还多了一个_vfptr放在对象的前面(注意有些平台可能会放在对象的后面,这个跟平台有关),对象中的这个指针我们称它为虚函数表指针。一个含有虚函数的类中至少都有一个虚函数表指针,因为虚函数的地址要被放到虚函数表(虚表)中。

    示例代码:

    //1.增加一个派生类Derive去继承Base
    //2.Derive中重写Func1
    //3.Base再增加一个虚函数Fun2和一个普通函数Fun3
    class Base
    {
    	virtual void Func1()
    	{
    		cout << "Base::Func1()" << endl;
    	}
    
    	virtual void Func2(){
    		cout << "Base::Func2()" << endl;
    	}
    
    	void Func3(){
    		cout << "Base::Func3()" << endl;
    	}
    
    private:
    	int _b = 1;
    };
    
    class Derive : public Base
    {
    public:
    	virtual void Func1(){
    		cout << "Derive::Func1()" << endl;
    	}
    private:
    	int _d = 2;
    };
    
    int main()
    {
    	Base b;
    	Derive d;
    	system("pause");
    	return 0;
    }
    

    这里我们打开监视窗口,不难发现以下几点问题:
    在这里插入图片描述
    在这里插入图片描述
    a. 派生类对象也有一个虚表指针,d对象由两部分构成,一部分是父类继承下来的成员,另一部分是自己的成员。
    b.基类b对象和派生类d对象虚表是不一样的,这里我们发现Func1完成了重写,所以d的虚表中存的是重写的Derive::Func1,所以虚函数的重写也叫覆盖。
    c.另外Func2继承下来后是虚函数,所以放进了虚表,Func3也继承下来了,但不是虚函数,所以不放在虚表中。
    d.虚函数表本质是一个存虚函数指针的指针数组,这个数组最后面放了一个nullptr。
    总结:派生类的虚表生成:
    (1)先将基类中的虚表内容拷贝一份到派生类虚表中;
    (2)如果派生类重写了基类中的某个虚函数,用派生类自己的虚函数覆盖虚表中基类的虚函数;
    (3)派生类自己新增加的虚函数按其在派生类中的声明次序增加到派生类的虚表的最后。

    多态实现的原理:
    分析了这么多,我们依旧拿上边“买票”为例,Func函数传Person调用的Person::BuyTicket,传Student调用的是Student::BuyTicket.

    class Person
    {
    public:
    	virtual void BuyTicket()
    	{
    		cout << "买票-全价" << endl;
    	}
    };
    
    class Student : public Person
    {
    public:
    	virtual void BuyTicket(){
    		cout << "买票-半价" << endl;
    	}
    };
    
    void Func(Person& p)
    {
    	p.BuyTicket();
    }
    
    int main()
    {
    	Person Mike;
    	Func(Mike);
    
    	Student John;
    	Func(John);
    
    	system("pause");
    	return 0;
    }
    

    在这里插入图片描述
    这样就实现了不同对象去完成同一行为时,展现出不同的形态。

    动态绑定与静态绑定:
    a. 静态绑定又称为前期绑定(早绑定),在程序编译期间确定了程序的行为,也称为静态多态 ,例如:函数重载。
    b. 动态绑定又称为后期绑定(晚绑定),是在程序运行期间,根据具体拿到的类型确定程序的具体行为,调用具体的函数,也称为动态多态

    下边给大家贴了一个链接,这个博文更好地讲解了多态,希望对大家有所帮助。
    https://blog.csdn.net/u012630961/article/details/81226351

    展开全文
  • 名词解释

    2018-07-10 13:10:46
    1.SNPSNP:Single Nucleotide Polymorphisms单核苷酸多态性,主要是指在基因组水平上由单个核苷酸的变异所引起的DNA序列多态性2.InDelInDel (insertion-deletion) 插入缺失标记,指的是两种亲本中在全基因组中的差异...

    1.SNP

    SNP:Single Nucleotide Polymorphisms单核苷酸多态性,主要是指在基因组水平上由单个核苷酸的变异所引起的DNA序列多态性

    2.InDel

    InDel (insertion-deletion) 插入缺失标记,指的是两种亲本中在全基因组中的差异,相对另一个亲本而言,其中一个亲本的基因组中有一定数量的核苷酸插入或缺失

    3.SNV

    SNV:单核苷酸位点变异(single nucleotide variants)在研究癌症基因组变异时,相对于正常组织,癌症中特异的单核苷酸变异是一种体细胞突变(somatic mutation).

    4.BQSR:碱基质量重打分(Bsae Quality Score Recalibration)


    展开全文
  • 什么是类的多态性

    千次阅读 2013-11-11 22:57:55
    同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果,这就是多态性。C#多态性通过派生类覆写基类中的虚函数型方法来实现。 C#多态性分为两种,一种是编译时的多态性,一种是运行时的多态性。 ◆编译...

    理解C#多态性之前首先理解一下什么叫多态。同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果,这就是多态性。C#多态性通过派生类覆写基类中的虚函数型方法来实现。

    C#多态性分为两种,一种是编译时的多态性,一种是运行时的多态性。

    ◆编译时的多态性:编译时的多态性是通过重载来实现的。对于非虚的成员来说,系统在编译时,根据传递的参数、返回的类型等信息决定实现何种操作。

    ◆运行时的多态性:运行时的多态性就是指直到系统运行时,才根据实际情况决定实现何种操作。C#中运行时的多态性是通过覆写虚成员实现。

     C++代码:

     这就是众所周知的的多态。现代面向对象语言对这个概念的定义是一致的。其技术基础在于继承机制和虚函数。例如,我们可以定义一个抽象基类Vehicle和两个派生于Vehicle的具体类Car和Airplane: 
        // dynamic_poly.h 
        #include 
        // 公共抽象基类Vehicle 
        class Vehicle 
        { 
        public: 
         virtual void run() const = 0; 
        }; 
        // 派生于Vehicle的具体类Car 
        class Car: public Vehicle 
        { 
        public: 
         virtual void run() const 
         { 
         std::cout << "run a car\n"; 
         } 
        }; 
        // 派生于Vehicle的具体类Airplane 
        class Airplane: public Vehicle 
        { 
        public: 
         virtual void run() const 
         { 
         std::cout << "run a airplane\n"; 
         } 
        }; 
    客户程序可以通过指向基类Vehicle的指针(或引用)来操纵具体对象。通过指向基类对象的指针(或引用)来调用一个虚函数,会导致对被指向的具体对象之相应成员的调用: 

        // dynamic_poly_1.cpp 
        #include 
        #include 
        #include "dynamic_poly.h" 
        // 通过指针run任何vehicle 
        void run_vehicle(const Vehicle* vehicle) 
        { 
         vehicle->run(); // 根据vehicle的具体类型调用对应的run() 
        } 
        int main() 
        { 
         Car car; 
         Airplane airplane; 
         run_vehicle(&car); // 调用Car::run() 
         run_vehicle(&airplane); // 调用Airplane::run() 
        }

     
    此例中,关键的多态接口元素为虚函数run()。由于run_vehicle()的参数为指向基类Vehicle的指针,因而无法在编译期决定使用哪一个版本的run()。在运行期,为了分派函数调用,虚函数被调用的那个对象的完整动态类型将被访问。这样一来,对一个Car对象调用run_vehicle(),实际上将调用Car::run(),而对于Airplane对象而言将调用Airplane::run()。 

    或许动态多态最吸引人之处在于处理异质对象集合的能力: 
        // dynamic_poly_2.cpp 
        #include 
        #include 
        #include "dynamic_poly.h" 
        // run异质vehicles集合 
        void run_vehicles(const std::vector< Vehicle* >& vehicles) 
        { 
         for (unsigned int i = 0; i < vehicles.size(); ++i) 
         { 
         vehicles[i]->run(); // 根据具体vehicle的类型调用对应的run() 
         } 
        } 
        int main() 
        { 
         Car car; 
         Airplane airplane; 
         std::vector< Vehicle* > v; // 异质vehicles集合 
         v.push_back(&car); 
         v.push_back(&airplane); 
         run_vehicles(v); // run不同类型的vehicles 
        } 

    在run_vehicles()中,vehicles[i]->run()依据正被迭代的元素的类型而调用不同的成员函数。这从一个侧面体现了面向对象编程风格的优雅。 

     

    C#代码

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;

    namespace WindowsFormsApplication1
    {
        public class Vehicle
        {
            public virtual string Run()
            {
                return "aaa";
            }
        }
        public class Car : Vehicle
        {
            public override string Run()
            {
                return "running a car!";
            }
       
        }
        public class Airplane : Vehicle
        {
            public override string Run()
            {
                return "fly a Airplance!";
            }

        }
       
        public partial class Form1 : Form
        {
           
            public Form1()
            {
                InitializeComponent();
            }
     
            private void Form1_Load(object sender, EventArgs e)
            {
                Vehicle v = new Vehicle();
                Car c = new Car();
                Airplane a = new Airplane();
                Console.WriteLine(v.Run());
                Console.WriteLine(c.Run());
                Console.WriteLine(a.Run());
            }
          
        }
    }

    展开全文
  • C#之多态性总结

    千次阅读 热门讨论 2014-03-09 14:48:25
    起初接触到这个名词的时候,是在看C++看到的,里边写的概念还是比较好理解的。但是这次看到了C#中关于多态的视频的时候,讲的我是云里雾里...同时要多态性是通过派生类覆写基类中的虚函数型方法来实现的。  说到这里

        起初接触到这个名词的时候,是在看C++看到的,里边写的概念还是比较好理解的。但是这次看到了C#中关于多态的视频的时候,讲的我是云里雾里的。脑子里除了雾还是雾。不过还好,有个大神,还有巨人的帮助。让我渐渐扒开雾层,重见光明。

        多态就是同一操作作用于不同对象,可以有不同的解释,产生不同的执行结果。这就是多态性。同时要多态性是通过派生类覆写基类中的虚函数型方法来实现的。

        说到这里,就不得不说一下重载和覆写。

        什么是重载呢?就是一个类中的方法与另一个方法同名,但是参数表不同,这种方法称之为重载方法

        比如说:

         public void ZhuGuo()
      {
          this.Guo="空气";
       }
        public void ZhuGuo(string tie)
       {
           this. Guo=tie;
        }
    
    	

            这个例子就是,比如我是个铸锅匠,不管是铁锅还是铝锅都会铸,顾客拿来铁可以铸铁锅,拿来铝可以铸铝锅,什么都没带来就用空气来给他铸个空气锅。这样一样的方法,但是所带来的材料(方法的参数不同),就会出现 不同的结果。这样重载就可以使功能扩展。

            什么是重写呢?重写顾名思义,是重新设计了方法的实现,这个“重新设计”的基础是方法名和参数完全一致,但是内部实现体不一样。重写一般发生在父类和子类之间,一般父类定义一个虚方法或抽象方法,子类根据具体情况“重写”其中的实现。

    比如:形状都有大小,圆和方都属于形状。他们都有各自的大小。通过重写可以得到他们各自的大小。

    先定义一个抽象类——shape ,其中GetSide(得到图形大小)是一个虚方法。

            abstract public class shape
            {
                abstract public int GetSide();
            }
    
     

            如果要是想得到圆的大小,就要重新写一下GetSide这个方法,来得到圆的大小

                public class 圆 : shape
                {
                    public override int GetSide()
                    {
                        return 1;
                    }
                }
    


    同样,方也有自己的大小。这样我们也要重写一下GetSide这个方法。来得到方的实际大小

                public class 方 : shape
                {
                    public override int GetSide()
                    {
                        return 2;
                    }
                }
    

    这样我们就可以使用同一种方法,来实现不同的效果(功能),这样就是面向对象设计的多态性。多态性就是父类使用子类的方法,通过声明父类实例化子类。就像一个父亲拥有好几个儿子,他们都会演奏,当要求父亲开一场演奏会的时候,父亲就会下达演奏这个命令,各个儿子根据自己的情况,演奏不同的乐器,这样就构成了一场完美的演奏会,完成了父亲的任务。

                                                             知识来源于生活。





    展开全文
  • 在生物信息中会出现很的特殊名词,从这次内容开始,我们将逐渐推送一些生物信息相关的一些名词解释。转录组测序:转录组即特定细胞在某一功能状态下所能转录出来的所有RNA的总和,包括mRNA和非编码RNA。转录组研究...
  • 多态性可以简单地概括为“一个接口,多种方法”,程序在运行时才决定调用的函数,它是面向对象编程领域的核心概念。多态(polymorphisn),字面意思多种形状。 C++多态性是通过虚函数来实现的,虚函数允许子类重新定义...
  • java多态性浅析

    千次阅读 多人点赞 2018-07-18 14:07:58
    多态性的描述形式: 多态性严格来讲,有两种描述形式: 一、方法的多态性: ① 方法的重载:同一个方法名称,会根据传入参数的类型及个数不同执行不同的方法体; ② 方法的覆写: 同一个方法,会根据...
  • 软件工程名词解释

    万次阅读 2019-11-06 16:01:00
     多态性(Polymorphism)是指在父类中定义的属性或服务被子类继承后,可以具有不同的数据类型或表现出不同的行为。 主动对象  主动对象(Active Object)是一组属性和一组服务的封装体,其中至少有一个服务...
  • 文章目录多态性 多态性 一个对象具有多种形态。 例如:小明是一个对象,这个对象既有学生形态,也有人类形态。 格式: 代码中多态性的体现,父类引用指向子类对象。【左父右子】 父类名称 对象名=new 子类名称(); ...
  • NGS基础名词解释(1)

    千次阅读 2017-12-06 13:44:21
    NGS基础名词解释
  • C++名词解释

    千次阅读 2017-07-12 11:35:44
    C++名词解释 1. 保留字reserved word  C++中,保留字也称关键字,它是预先定义好的标识符。见关键字的解释。2.关键字key word  C++中已经被系统定义为特殊含义的一类标识符。C++中的关键字有: auto double ...
  • 本节书摘来自异步社区《UML面向对象设计基础》一书中的第1章1.8节多态性,作者【美】Meliir Page-Jones,更多章节内容可以访问云栖社区“异步社区”公众号查看。 1.8 多态性UML面向对象设计基础“polymorphism(多态...
  • 单核苷酸多态性(single nucleotide polymorphism,SNP),主要是指在基因组水平上由单个核苷酸的变异所引起的DNA序列多态性。它是人类可遗传的变异中最常见的一种。占所有已知多态性的90%以上。SNP在人类基因组...
  • java基础--名词解释汇总

    千次阅读 多人点赞 2017-06-01 16:05:46
    下面为大家汇总了Java名词解释大全,希望对同学们学习java有帮助!  面向对象:面向对象程序设计(Object-Oriented Programming)是一种起源于六十年代,发展已经将近三十年的程序设计思想。其自身理论已十分完善...
  • 一,类的封装是指在定义一个类时,将类中的属性私有化,即使用private关键字来修饰,私有属性只能在它所在类中被访问。一般需要获取属性值的方法和设置属性值的方法来让外界访问私有属性。 package encapsulation;...
  • java名词解释

    2016-08-18 09:10:24
    区别面向对象的开发和传统过程的开发的要素有:对象识别和抽象、封装、多态性和继承。(参见百度百科:面向对象) 面向对象要素:封装、多态、继承 Java名词解释: ...
  • 操作系统名词解释

    千次阅读 2016-10-12 23:46:05
    第1部分 操作系统概论名词解释 脱机输入/输出 具体的输入/输出不需要在主计算机上进行的方式也称“脱机输入/输出” 批处理 作业是由操作系统成批地进行处理,操作系统能自动地从输入池读入下一个作业,并予以...
  • 软件测试的名词解释

    2019-09-22 00:34:21
    软件测试的名词解释 以下是软件测试中常用但极易混淆的一些名词,我会不断更新,欢迎各位提出不同的意见。 缺陷(fault) 是程序实现或设计中的错误、失误。 错误(error) 同“缺陷”。 失效...
  • 1 RRC 常用名词解释

    2020-12-18 11:51:56
    常用名词解释 1. RRC 无线资源控制(Radio Resource Control,RRC),又称为无线资源管理(RRM)或者无线资源分配(RRA),是指通过一定的策略和手段进行无线资源管理、控制和调度,在满足服务质量的要求下,尽可能...
  • c++名词解释

    2012-12-23 13:21:37
    见关键字的解释。 2.关键字:C++中已经被系统定义为特殊含义的一类标识符。 3.标识符:对变量、函数、标号和其它各种用户自定义对象的命名。在C++中,标识符长度没有限制,第一个字符必须是字母或下划线,其后若...
  • 面向对象的特点,封装性,继承性,多态性

    万次阅读 多人点赞 2015-01-29 19:37:02
    4.多态性,简单来说就是一个程序中同名的多个不同方法共存的情况,通常使用方法的重载和重写(也叫覆盖)来实现类的多态性多态性允许以统一的风格编写程序,以处理种类繁多的已存在的类以及相关类,多态的实现并不...
  • RNA-Seq名词解释

    万次阅读 多人点赞 2016-11-14 15:13:07
    RNA-Seq名词解释 1.index 测序的标签,用于测定混合样本,通过每个样本添加的不同标签进行数据区分,鉴别测序样品。 2.碱基质量值 (Quality Score或Q-score)是碱基识别(Base Calling)出错的概率的...
  • C++常用名词解释汇总

    千次阅读 2018-03-04 16:58:02
    C++常用名词解释汇总new运算符:对象创建的操作符。delete运算符:对象释放操作符,触发析构函数。内存泄露:操作堆内存时,如果分配了内存,就有责任回收它,否则这块内存就无法重新使用,称为内存泄漏。自动变量:...
  • 图形学名词解释

    千次阅读 2011-10-16 23:21:28
    图形学名词解释  3D 三维(three dimension)。客观世界中静止的物体都是三维的,在计算机图形学中常在一定的坐标系中用(x,y,z)坐标系列表示物体。 3D modeling 3D建模。用三维坐标来描述物体的形状。在...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 8,095
精华内容 3,238
关键字:

多态性名词解释