精华内容
下载资源
问答
  • 2021-02-23 20:19:17

    1、多态性
    一个事物的多种形态。
    2、什么是多态性
    对象的多态性:父类的引用指向子类的对象或子类的对象赋给父类的引用。
    3、多态的使用:虚拟方法调用
    有了对象的多态以后,我们在编译期,只能调用父类中声明的方法,但在运行期,我们实际执行的是子类重写父类的方法。
    总结:编译看左边,运行看右边
    4、多态性的前提:(1)类的继承关系;(2)方法的重写。
    5、对象的多态性,只适用于方法,不适用于属性。
    方法的编译看左边,运行看右边;属性的编译和运行都看左边。
    扩展:虚拟方法
    子类中定义了与父类同名同参数的方法,在多态情况下,将此时父类的方法称为虚拟方法,父类根据赋给它的不同子类对象,动态调用属于子类的该方法。这样的方法调用在编译期是无法确定的。

    更多相关内容
  • 继承是面向对象程序设计的主要特征之一,允许重用现有类去创建新类的过程。下面使用示例学习一下c#继承与多态
  • 多态使用的四种方式

    2021-12-12 15:46:44
    多态使用: 父类的指针或引用指向子类对象; 调用方式1.在函数调用中,通过父类指针指向子类: //3、抽象电脑基类,提供工作函数; class Computer { private: CPU* m_CPU; VideoCard* m_VideoCard; Memory*...

     多态使用:

    父类的指针或引用指向子类对象;

    调用方式1.在函数调用中,通过父类指针指向子类:

    //3、抽象电脑基类,提供工作函数;
    class Computer
    {
    private:
    	CPU* m_CPU;
    	VideoCard* m_VideoCard;
    	Memory* m_Memory;
    public:
    	Computer(CPU* CPU, VideoCard* VideoCard, Memory* Memory)
    //相当于  CPU* CPU=new HuaweiCPU,VideoCard* VideoCard= new HuaweiVideoCard, Memory* Memory=new HuaweiMemory
    	{
    		m_CPU = CPU;
    		m_VideoCard = VideoCard;
    		m_Memory = Memory;
    	}
    	//电脑工作函数;
    	void Runing()
    	{
    		m_CPU->Calculate();
    		m_VideoCard->Display();
    		m_Memory->Storage();
    	}
    };
    
    int main() 
    {
    	//创建第一个电脑;
    	//调用方式1.在函数中,通过父类指针指向子类:
    	Computer c1(new HuaweiCPU, new HuaweiVideoCard, new HuaweiMemory);
    	//电脑运行;
    	c1.Runing();
    
    	system("pause"); 
    	return 0;
    }

    调用方式2.在函数调用中,通过父类引用指向子类:

    void DoSpeak(Animal& animal)
    //相当于:Animal& animal=cat;;此时多态发生,vfptr指向cat;
    {
    	animal.Speak();
    }
     
    int main() 
    {
    	Animal animal;
    	DoSpeak(animal);
     
    	cat cat;
    	DoSpeak(cat);
     
    	system("pause"); 
    	return 0;
    }
    
    ————————————————
    版权声明:本文为CSDN博主「Bruce-嵌入式软件」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/weixin_46432495/article/details/121845728

    调用方式 3.在函数中,通过父类指针指向子类:

    
    int main() 
    {
    	DoDrink* c = new Coffee;//这里直接发生多态,将vfptr指向coffee的vftal
    	c->DoWork();
    	delete c;
    
    	system("pause"); 
    	return 0;
    }

    调用方式4.在函数中,通过父类引用指向子类:

     

    展开全文
  • 4.能够在派生类中使用构造函数和析构函数 5.学习虚基类在解决二义性问题中的作用。 6.熟悉多态分类,理解静态联编和动态联编概念。 7.掌握运算符重载方法。 8.理解虚函数、纯虚函数和抽象类概念。 9.掌握用...
  • 多态使用场合

    2020-08-25 17:24:01
    java 多态的一些使用场合

    多态的使用场合 (笔试)

    通过方法的参数传递形成多态;

    public static void draw(Shape s){    
        s.show(); 
    } 
    
    draw(new Rect(1, 2, 3, 4)); 
    

    Rect为Shape的子类

    在方法体中直接使用多态的语法格式

    Account acc = new FixedAccount();
    

    父类的引用指向子类的对象

    通过方法的返回值类型形成多态

    Calender getInstance(){   
        return new GregorianCalendar(zone, aLocale); 
    }
    Calender cal = Calender.getInstance();
    

    Calender为抽象类,返回值为子类

    展开全文
  • 文章目录前言多态构成多态的条件虚函数虚函数的重写(覆盖):多态调用虚函数的规则析构函数的重写(基类与派生类析构函数的名字不同) 多态 简单的说:多态就是根据你传入的不同的对象,去做同一样的事情,会有不同的...

    前言

    1. 多态的理解

    简单的说:多态就是根据你传入的不同的对象,去做同一样的事情,会有不同的结果和行为的表现产生;

    在C++中,传入不同的对象意思:给父类传入不同的子类;

    去做同一样的事意思是:父类指针或者引用调用了同一样的虚函数;

    产生不同的结果意思是:调用同样的虚函数,但是结果却不一样;


    2. 构成多态的条件

    继承中要构成多态还有两个条件:
    1. 必须通过基类的指针或者引用调用虚函数;
    2. 被调用的函数必须是虚函数,且派生类必须对基类的虚函数进行重写;


    3. 虚函数

    虚函数:即被virtual修饰的类非静态成员函数称为虚函数。(静态成员不可以作为虚函数,全局函数也不行)
    虚函数的重写;

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

    4. 虚函数的重写(覆盖)

    派生类中有一个跟基类完全相同的虚函数(即派生类虚函数与基类虚函数的返回值类型、函数名字、参数列表完全相同),称子类的虚函数重写了基类的虚函数。

    class Person {
    public:
    virtual void BuyTicket() { cout << "买票-全价" << endl; }
    };
    /*注意:在重写基类虚函数时,派生类的虚函数在不加virtual关键字时,虽然也可以构成重写(因为继承后
    基类的虚函数被继承下来了在派生类依旧保持虚函数属性),但是该种写法不是很规范,不建议这样使用*/
    /*void BuyTicket() { cout << "买票-半价" << endl; }*/ 
    class Student : public Person {
    public:
    virtual void BuyTicket() { cout << "买票-半价" << endl; }
    

    5.多态调用虚函数的规则

    构成多态,跟父类的指针或者引用的类型没有关系,传的哪个类型的对象,调用的就是这个类型的虚函数 – 跟对象有关;
    不构成多态,调用就是父类指针或者引用类型的函数 – 跟类型有关;


    #include<iostream>
    using namespace std;
    class Person {
    public:
    	virtual void BuyTicket() { cout << "买票-全价" << endl; }
    };
    class Student : public Person {
    public:
    	virtual void BuyTicket() { cout << "买票-半价" << endl; }
    };
    void test1(Person& p)
    {
    	p.BuyTicket();
    }
    void test2(Person* p)
    {
    	p->BuyTicket();
    }
    int main()
    {
    	Person ps;
    	Student st;
    	//父类引用调用虚函数,子类重写虚函数,构成多态;那么调用函数就传入的对象有关
    	//这里传入的对象ps的类型为 Person 所以调用Person的虚函数;
    	Person& p1 = ps;
    	p1.BuyTicket();
    	//父类引用调用虚函数,且子类重写父类虚函数,构成多态,那么调用函数就和传入的对象有关;
    	//这里传入的对象是 Student,所以调用的是Student的虚函数;
    	Person& p2 = st;
    	p2.BuyTicket();
    
    	//指针的分析和引用一致
    	Person* p3 = &ps; //构成多态
    	p3->BuyTicket();
    
    	Person* p4 = &st; //构成多态
    	p4->BuyTicket();
    
    	getchar();
    	return 0;
    }
    

    符合预期:
    在这里插入图片描述


    测试:假如不是父类指针或者引用调用虚函数会发生什么;

    去除条件1,不是父类指针或引用而是父类对象去调用虚函数,是否会发生多态?

    1. 假如 子类对象赋值给父类对象会不会发生多态?肯定不会?所以父类对象调用虚函数,只看父类的类型;
    	//子类对象赋值给父类对象,没有父类指针或引用指向子类对象,这不会构成多态,所以调用虚函数
    	//只看p5的类型;
    	Person p5 = st;
    	p5.BuyTicket(); //调用的是父类的虚函数,不构成多态
    
    1. 即使有父类的指针或引用调用了虚函数,假如子类没有重写虚函数,依旧不会发生多态,没有多态那么,父类指针或引用去调用虚函数时候,都是看父类的类型的;
      (ps:我们可以修改父类和子类虚函数,只要不构成重写,就可以验证我上面的结论)

    6. 析构函数的重写(基类与派生类析构函数的名字不同)

    如果基类的析构函数为虚函数,此时派生类析构函数只要定义,无论是否加virtual关键字,都与基类的析构函数构成重写,虽然基类与派生类析构函数名字不同。虽然函数名不相同,看起来违背了重写的规则,其实不然,这里可以理解为编译器对析构函数的名称做了特殊处理,编译后析构函数的名称统一处理成destructor。


    class Person {
    public:
    virtual ~Person() {cout << "~Person()" << endl;}
    };
    class Student : public Person {
    public:
    virtual ~Student() { cout << "~Student()" << endl; }
    };
    // 只有派生类Student的析构函数重写了Person的析构函数,下面的delete对象调用析构函数,才能构成
    //多态,才能保证p1和p2指向的对象正确的调用析构函数。
    int main()
    {
    	Person* p1 = new Person;
    	Person* p2 = new Student;
    	
    	delete p1; // 编译器默认转化了调用虚构函数的形式 p1->destructor()      
    	delete p2; // 编译器默认转化了调用虚构函数的形式 p2->destructor(),
    				//由于构成多态,所以会正确的嗲用传入对象是子类的虚析构函数
    	return 0;
    }
    

    构成多态,正确的调用了子类的析构函数;
    这也是唯一的场景:是析构函数,需要写成虚析构的形式;
    在这里插入图片描述


    没有发生多态时候,不管你的父类还是子类是否为虚析构,都可以正确的调用析构函数
    在这里插入图片描述


    非虚析构函数,依旧可以正确释放
    在这里插入图片描述


    上面两种原因很简单:继承体系中,子类对象指向析构时候,本身就会现执行子类再执行父类,和你的析构函数是否为虚函数没关系;


    所以说析构函数是否需要写成虚析构函数,首先得发生多态行为,才需要父类析构写成虚析构,这也才可以保证delete 父类指针时候,能够去调用子类的析构函数;


    本质我们 delete 父类指针,就是为了析构子类对象的,因为父类指针指向了子类对象,我们希望的就是做这样的事;delete父类指针,为了析构子类对象,那么就需要发生多态,这个行为才会产生;有多态,就必须,子类重写父类的虚析构函数;


    7. 设计一个不能被继承的基类

    在C++98时候,有一种方式可以设计不被继承:那就是设计基类的构造函数为私有的

    #include<iostream>
    using namespace std;
    
    
    class Base{
    private:
    	Base(){
    		cout << "Base::Base()的构造函数调用" << endl;
    	}
    private:
    	int _b;
    };
    class Derive :Base{
    private:
    	int _d;
    };
    int main(){
    
    	Derive son;
    
    	return 0;
    }
    
    

    这种方式:当我屏蔽了:Derive son这句代码,也就是,不创建子类对象时候,上面的代码编译是可以通过的;

    但是当我写上了Derive son也就是创建子类对象时候,那么就会编译报错:原因就是基类的构造函数为私有,派生类创建对象时候,也是执行Derive son代码时候,需要先调用父类的构造函数,但是由于父类的构造函数时私有的,不可以被调用,所以就会编译报错了;

    设计基类的构造函数是私有的:这也就解决了一个类不可以被继承的情况;


    8. final关键字和override 关键字

    C++11通过新增一个关键字final:解决了基类不可以被继承问题, 也就是不需要设计基类的构造函数为私有的;
    具体操作就是:在声明基类的后面加多一个关键字 final就可以达到效果;

    class Base final{//final关键字修饰,使得该类不可以被继承
    public:
    	Base(){
    		cout << "Base::Base()的构造函数调用" << endl;
    	}
    private:
    	int _b;
    };
    class Derive :public Base{
    private:
    	int _d;
    };
    int main(){
    
    	Derive son;
    
    	return 0;
    }
    

    在这里插入图片描述


    final关键还可以修饰基类的虚函数,目的就是为了使得基类的虚函数不被子类重写;

    class Base {
    public:
    	Base(){
    		cout << "Base::Base()的构造函数调用" << endl;
    	}
    	virtual void fun() final{ //使得该虚函数不能够被重写
    		cout << "Base::fun()被调用" << endl;
    	}
    private:
    	int _b;
    };
    
    class Derive :public Base{
    	public
    	virtual void fun(){ //由于基类这个函数fun被final修饰,所以派生类不可以重写
    		cout << "Derive::fun()被调用" << endl;
    	}
    private:
    	int _d;
    };
    int main(){
    
    	Derive son;
    
    	return 0;
    }
    

    在这里插入图片描述


    c++11还有一个关键字override,它是修饰派生类的虚函数,目的为的是:派生类必须重写基类虚函数,如果基类没有该虚函数,那么就会报错,或者派生类重写错乱基类虚函数,那么就会报错;

    反正就是在基类中找不到你要重写的虚函数,那么就会直接报错;

    所以说:override 有检查机制,帮你检查你的派生类是否正确的重写了基类的虚函数;


    class Base {
    public:
    	Base(){
    		cout << "Base::Base()的构造函数调用" << endl;
    	}
    	virtual void fun() { 
    		cout << "Base::fun()被调用" << endl;
    	}
    private:
    	int _b;
    };
    
    class Derive :public Base{
    public:
    	virtual void fun1() override{ 
    		cout << "Derive::fun()被调用" << endl;
    	}
    private:
    	int _d;
    };
    int main(){
    
    	Derive son;
    
    	return 0;
    }
    

    在这里插入图片描述


    9. 抽象类

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


    由于抽象类不能实例化对象,所以虚函数实现也是没有任何意义的,所以不会有人实现纯虚函数;
    纯虚函数是可以实现的,但是就是没有意义罢了;


    在这里插入图片描述

    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();
    }
    

    有纯虚函数,只能用父类指针或引用指向子类对象了,不可能再指向父类对象,因为父类对象是不可以被创建的;

    10. 接口继承和实现继承区别

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


    展开全文
  • C++多态的概念与使用(详细介绍)

    千次阅读 2022-04-07 13:53:51
    多态的概念:通俗来说,就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会产生出不同的状态。 下面以学生买票为例说明多态的特性。 多态的构成条件 多态是在不同继承关系的类对象,去调用同一函数,...
  • 接口的多态可以直接使用实现类中重写的方法,不能直接使用实现类新增方法。 interface MyInterface { void method(); } public class MyClass implements MyInterface { @override void method(){} void new...
  • C++中的多态及简单使用 多态的意义 使用多态是为了让有多种可能实现的函数,在需要增加功能或者说拓展时将改动减到最少。也就是使程序更加面向拓展。例如动物都会喝水,但是人喝水和大象喝水是不同的,那么在写...
  • 如果说OOP的封装和继承使用起来更加直观易用,那么作为第三大特性的多态,在实践中真正运用起来就不那么容易。有的读者OOP编程初期,可能对多态的价值体会不深刻,甚至都已经淡忘它的存在。 那么问题就在:多态到底...
  • C++多态的用法详解

    千次阅读 多人点赞 2022-04-21 16:38:26
    C++多态是在继承的基础上实现的,了解多态之前我们需要掌握一定的C++继承的知识,本文将介绍C++中多态的概念,构成条件以及用法。
  • 多态的应用场景

    2022-03-31 14:11:58
    2.当用增强for循环遍历集合时,使用Object类遍历所有元素 二.数据库驱动 JAVA定义了JDBC Driver接口,不同的数据库开发商按照规范实现该接口,这也是多态的一种表现形式(一个接口对应不同的实现类)。 // ...
  • 记个笔记:Java在开发过程中尽量多使用多态,除了父类子类之间的多态,还有接口,在进行类型强转时候,如果是一个子类实现了某个接口,而父类引用指向这个子类,这个引用强制转成接口类型,这时即便是这个引用(父类...
  • 多态注意点: 1:多态情况下,子类中存在跟父类同名的成员变量时,访问的是父类的成员变量 2: 多态情况下,子类中存在跟父类同名的非静态方法时,调用的是子类中的方法 3: 多态情况下,子类中存在跟父类同名的静态...
  • java中多态运用

    多人点赞 2022-05-20 14:29:12
    2.多态使用 (1)要有继承关系的存在 (2)要有方法的重写 (3)要有父类引用指向子类对象 3.多态成员变量的特点 编译看左边,运行看左边。 Fu f=new Zi(); System.out.println(f.num);//f是Fu中的值,只能...
  • 源代码: package tiaoshi; class Fu{ public void show() { System.out.println(“Fu show”); } } class Zi extends Fu{ public void show() { System.out.println(“Zi show”);...System.out.prin...
  • 这是多态中的父类引用指向子类对象,可以调用子类中重写了父类的方法。 但我有一点不明白,既然调用重写了父类方法的子类,那么我直接创建一个子类的对象, 也可以达到相同的效果,那我为什么还要使用这样的向上...
  • 多态是JAVA的三大特性之一,多态在JAVA中也有广泛的应用,本文简单介绍了JAVA中几种多态的应用场景供大家学习。 一、常用类 1.1集合中的add()方法可以添加任意类型的数据,原因是Object是所有数据类型的父类。 1.2当...
  • Web Services可以支持多态,不过仅仅限制在可以直接引用Web Services的时候,本文也只是起到抛砖引玉的效果,
  • 这些能力和弹性使C++成为一个无可匹敌的工具,但也可能引发使用者的某些迷惑,比如多态。在这几种编程泛型中,面向对象编程、泛型编程以及很新的元编程形式都支持多态的概念,但又有所不同。 C++支持多种形式的多态...
  • 多态的应用实际举例

    2021-03-25 14:45:49
    多态的应用 1.多态数组:数组的定义类型为父类类型,里面保存的实际元素类型为子类类型 2.多态参数:方法定义的形参类型为父类类型,实参允许为子类类型 public class Homework13 { public static void main(String...
  • 主要介绍了C#使用虚拟方法实现多态,涉及C#多态的实现技巧,具有一定参考借鉴价值,需要的朋友可以参考下
  • OC-多态使用介绍

    千次阅读 2015-08-27 23:02:20
    1、什么是多态?  多态就是某一类事物的多种形态。  程序中的多态,不同的对象以自己的方式相应相同名称方法的能力称为多态 2、多态的条件:1)、有继承关系,有方法重写  2)、父类的声明变量指向子类对象。...
  • Java——多态

    2020-12-21 19:51:44
    Java——多态 多态的特性 1.可替换性(substitutability)。多态对已存在代码具有可替换性。 例如,多态对圆Circle类工作,对其他任何圆形几何体,如圆环, 也同样工作。 2.可扩充性(extensibility)。多态对代码...
  • Java基础(多态的理解与应用)

    千次阅读 2021-02-28 16:27:20
    1.多态概述多态是继封装、继承之后,面向对象的第三大特性。多态现实意义理解:现实事物经常会体现出多种形态,如学生,学生是人的一种,则一个具体的同学张三既是学生也是人,即出现两种形态。Java作为面向对象的...
  • 在面向对象C++编程中,多态是OO三大特性之一,这种多态称为运行期多态,也称为动态多态;在泛型编程中,多态基于template(模板)的具现化与函数的重载解析,这种多态在编译期进行,因此称为编译期多态或静态多态。在...
  • Java如何实现多态

    千次阅读 2021-02-12 10:24:44
    核心:1、多态就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编译时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底...
  • java多态的理解

    千次阅读 2020-12-30 23:58:57
    使用多态,我们可以很好的完成代码的解耦和工作,加强代码的可扩展性,是代码更加灵活,在不改变原有接口方法的情况下简化流程等,总结一下就是: 减耦合 增强可以替换性 可扩展性 灵活性等… 三、实现多态的三个...
  • 本文讲解了什么是JAVA多态和Java多态是如何实现的,在使用Java多态时需要注意什么,具体大家看下面的内容
  • 多态的实现是因为使用了一种动态绑定的机制,在编译期间不确定调用函数的地址,在调用虚函数的时候,去查询虚函数指针所指向的虚函数表。 派生类生成的对象中的虚函数指针指向的是派生类的虚函数表,因此无论是基类...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 417,465
精华内容 166,986
关键字:

多态使用