-
2021-02-01 21:27:39
多态的基本概念
多态:同一种事物表现出来的多种形态。
多态语法格式
格式为:父类类型的引用指向子类类型的对象。如下所示
Person person=new Worker();
多态的特点
(1)当父类类型的引用指向子类类型的对象时,可以直接访问父类独有的方法。
(2)当父类类型的引用指向子类类型的对象时,无法直接访问子类独有的方法,但可以通过强制类型转换访问。
(3)对于父子类都有的非静态方法,编译阶段调用父类的方法,运行阶段调用子类的方法(动态绑定)。
(4)对于父子类都有的静态方法,编译和运行阶段都调用父类的静态方法。引用数据类型的转换
引用数据类型之间的转换有两种,一是自动类型转换,二是强制类型转换。自动类型转换是指由小转大,由子类转换为父类,也称作向上转换。强制类型转换是指由大转小,由父类转换为子类,也称作向下转换或者显示转换(因需加上需转换的类型)。如下所示
Worker w=new Worker(); Person p=w;//自动类型的转换
Person p=new Worker(); ((Worker)p).work();//强制类型转换,work()是Worker独有的方法
强转的注意事项
(1)当引用变量强转为非指向对象类型的对象时,编译通过,运行时会出现类型转换异常(ClassCastException)。例如:
Person p=new Worker();//Worker,Dancer继承自Person类 ((Dancer)p).dance();//强转为非指向对象的类型,出现异常
(2)为了避免该错误的放生,进行转换前可通过 if(引用变量 instanceof 数据类型)判断能否进行强转。例如:
if(p instanceof Dancer) ((Dancer)p).dance(); else System.out.Println("类型错误,无法进行强转");
多态的实际意义
意义:多态的意义在于屏蔽不同子类的差异性实现通用的编程带来不同的效果。例如,通过多态实现一个方法可将参数对象的特征打印出来,其中参数对象可以是不同的子类对象。
先定义Worker,Dancer类继承自Person类public class Person { public void speak(){ System.out.println("我是Person"); } }
public class Worker extends Person{ @Override public void speak() {//重写父类方法 System.out.println("我是一个Worker"); } }
public class Dancer extends Person{ @Override public void speak() {//重写父类方法 System.out.println("我是一个Dancer"); } }
最后是测试类
public class PersonTest { public static void speak(Person p){ p.speak(); } public static void main(String[] args) { //将不同子类对象作为形参 PersonTest.speak(new Worker()); PersonTest.speak(new Dancer()); } }
运行结果如下
更多相关内容 -
C++多态概念和意义
2020-09-04 10:12:312、C++如何支持多态概念 3、多态内部运行剖析 4、多态的意义 5、修改示例代码 四、静态联编和动态联编 五、小结 一、什么叫重写 1、子类中可以重定义父类中已经存在的成员函数; 2、这种重定义发生在继承中...目录
一、什么叫重写
1、子类中可以重定义父类中已经存在的成员函数;
2、这种重定义发生在继承中,叫做函数重写;
3、函数重写是同名覆盖的一种特殊情况。
二、面向对象期望的重写
先来验证个小示例:
#include <QCoreApplication> #include <iostream> #include <QDebug> using namespace std; class Parent { public: void Printfln() { std::cout << "Parent: void Printfln()..." << std::endl; } }; class Child : public Parent { public: void Printfln() { std::cout << "Child: void Printfln()..." << std::endl; } }; void run(Parent *p) { p->Printfln(); } int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); Parent p; Child c; run(&p); run(&c); return a.exec(); }
1、示例分析
1、结果:结果是调用两次run函数打印的结果相同;
2、分析:
(1)编译期间,编译器只能根据指针的类型判断所指向的对象;
(2)根据赋值兼容性原则,编译器认为父类指针指向的是父类对象;
(3)run函数中的指针p,编译器不可能知道它指向的究竟是什么,但是编译器没理由报错,编译器认为最安全的做法就是调用父类Printfln()函数,因为父类和子类都有相同的Printfln()函数;
(4)因此,编译器结果只可能是调用父类定义的同名函数。
2、所期望的重写
面向对象的期望重写行为:根据实际的对象类型来判断如何调用重写函数;
(1)当父类指针(引用)指向父类对象,则调用父类中定义的成员函数;
(2)当父类指针(引用)指向子类对象,则调用子类中定义的重写函数。
三、多态的概念和意义
1、多态的概念
(1)根据实际的对象类型决定函数调用的具体目标;
(2)同样的调用语句在实际运行时有多种不同的表现形态体现,这就是多态,同一语句具有多种形态。
2、C++如何支持多态概念
(1)通过使用virtual关键字对多态进行支持;
(2)被virtual修饰的函数被重写后具有多种不同的表现形态;
(3)被virtual声明的函数称为虚函数。
3、多态内部运行剖析
父类和子类的对象,首地址都各自有一个虚函数表地址,该地址都保存着虚函数Printfln()的地址,在运行过程中:
(1)在父类指针(引用)p,指向父类对象,就相当于指向父类的虚函数表,从而在父类的虚函数表中找到Printfln()函数;
(2)在父类指针(引用)p,指向子类对象,相当于指向子类的虚函数表,从而在子类的虚函数表中找到Printfln()函数。
4、多态的意义
(1)在程序运行中展现出动态的特性;
(2)函数重写必须多态实现,否则没有任何意义;
(3)多态是面向对象组件化程序设计的基础特性。
5、修改示例代码
根据多态的概念,在程序中给父子类同名函数声明virtual关键字,只需要在父类中声明即可,在子类中可以不写,写了也是对的,编译器不会报错。
#include <QCoreApplication> #include <iostream> #include <QDebug> using namespace std; class Parent { public: virtual void Printfln() { std::cout << "Parent: void Printfln()..." << std::endl; } }; class Child : public Parent { public: void Printfln() { std::cout << "Child: void Printfln()..." << std::endl; } }; void run(Parent *p) { p->Printfln(); } int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); Parent p; Child c; run(&p); run(&c); return a.exec(); }
四、静态联编和动态联编
1、静态联编:在程序编译期间就能确定的具体的函数调用,如函数重载;
2、动态联编:在程序运行期间才能确定的具体的函数调用,如函数重写。
五、小结
1、函数重写只能发生在父类和子类之间;
2、多态是根据实际对象类型确定调用具体的函数;
3、virtual关键字是C++支持多态的唯一方式;
4、被重写的虚函数具有多种不同表现形态。
-
对Java中多态的意义理解
2022-02-25 17:55:08先看Java代码: public ... } } 运行结果: 总结:多态的意义就是,当new出来的对象中自己“独特的”方法时,默认采用申明类型中“普遍的”方法,“多态”这一词的含义就来源于这种用于对创造的对象的广泛性的意义。先看Java代码:
public class Example { public static void main(String[] args) { System.out.println("====人===="); Person person = new Person("叽里呱啦","默认皮肤"); person.say(); person.showSkin(); person.walk(); person.eat(); person.sleep(); //多态 System.out.println("====中国人===="); Person chinese = new Chinese("中文","黄皮肤"); chinese.say(); chinese.showSkin(); chinese.walk(); chinese.eat(); chinese.sleep(); System.out.println("====美国人===="); Person american = new American("英文","白皮肤"); american.say(); american.showSkin(); american.walk(); american.eat(); american.sleep(); } } class Person { String language; String skinColor; public Person() {} public Person(String language, String skinColor) { this.language = language; this.skinColor = skinColor; } public void say(){ System.out.println("说"+this.language); } public void showSkin(){ System.out.println(this.skinColor); } public void walk(){ System.out.println("人走路"); } public void eat(){ System.out.println("人吃饭"); } public void sleep(){ System.out.println("人睡觉"); } } class Chinese extends Person { public Chinese(){} public Chinese(String language, String skinColor) { super(language,skinColor); } } class American extends Person { public American(){} public American(String language, String skinColor) { super(language,skinColor); } }
运行结果:
总结:多态的意义就是,当new出来的对象中自己“独特的”方法时,默认采用申明类型中“普遍的”方法,“多态”这一词的含义就来源于这种用于对创造的对象的广泛性的意义。
-
8、多态的概念和意义
2020-08-05 19:00:02一、什么是多态? 1、多态初认识 多态也就是面向对象中期望的行为。 (1) 根据实际的对象类型判断如何调用重写函数 (2) 父类指针(引用)指向 父类对象则调用父类中调用的函数 子类对象则调用子类中定义的重写...此文编写参考狄泰软件学院唐佐林老师的视频课程,如有错误之处,欢迎指正。
1、多态初认识
多态也就是面向对象中期望的行为。
(1) 根据实际的对象类型判断如何调用重写函数
(2) 父类指针(引用)指向
父类对象则调用父类中调用的函数
子类对象则调用子类中定义的重写函数
总的来说就是根据实际的对象类型决定函数调用的具体目标,同样的调用语句在实际运行时有多种不同的表现形态。2、语法
通过关键字virtual来对函数进行声明
(1)被virtual声明的函数被重写后具有多态特性
(2)被virtual声明的函数叫虚函数
(3)要在父类中对函数进行声明下面通过一个实例来理解。
#include<iostream> #include<string> using namespace std; class Parent { public: virtual void print() { cout<<"I am Parent."<<endl; } }; class Child:public Parent { void print() { cout<<"I am Child."<<endl; } }; void how_to_print(Parent* p) { p->print(); } int main() { Parent p; Child c; how_to_print(&p); how_to_print(&c); return 0; }
分析:这里正常情况下会发生同名覆盖,但是将父类中的函数声明为虚函数后,就输出了期望的行为。3、多态的意义
在程序运行过程中展现出动态的特性
函数重写必须实现多态,否则没有意义
多态是面向对象组件化程序设计的基础特性4、理论中的概念
- 静态联编
在程序的编译期间就能够确定具体函数的调用
如:函数重载 - 动态联编
在程序实际运行后才能确定具体的函数调用
如:函数重写
下面通过实例来理解动态联编和静态联编
#include <iostream> #include <string> using namespace std; class Parent { public: virtual void func() { cout << "void func()" << endl; } virtual void func(int i) { cout << "void func(int i) : " << i << endl; } virtual void func(int i, int j) { cout << "void func(int i, int j) : " << "(" << i << ", " << j << ")" << endl; } }; class Child : public Parent { public: void func(int i, int j) { cout << "void func(int i, int j) : " << i + j << endl; } void func(int i, int j, int k) { cout << "void func(int i, int j, int k) : " << i + j + k << endl; } }; void run(Parent* p) { p->func(1, 2); // 展现多态的特性 // 动态联编 } int main() { Parent p; p.func(); // 静态联编 p.func(1); // 静态联编 p.func(1, 2); // 静态联编 cout << endl; Child c; c.func(1, 2); // 静态联编 cout << endl; run(&p); run(&c); return 0; }
运行结果:
5、江湖恩怨
#include<iostream> #include<string> using namespace std; class Boss { public: int fight() { int ret=10; cout<<"Boss::fight():"<<ret<<endl; return ret; } }; class Master { public: virtual int eightswords() { int ret=8; cout<<"Master::eightswords():"<<ret<<endl; return ret; } }; class newMaster:public Master { public: int eightswords() { int ret=Master::eightswords()*2; cout<<"Master::eightswords():"<<ret<<endl; return ret; } }; void pk(Master* m,Boss* b) { int zhuangzhu=m->eightswords(); int ermo=b->fight(); if(zhuangzhu<ermo) { cout<<"zhuangzhu is killed"<<endl; } else { cout<<"ermo is killed"<<endl; } } int main() { Master zhuangzhu; Boss ermo; cout<<"zhuangzhu vs ermo"<<endl; pk(&zhuangzhu,&ermo); cout<<endl; newMaster shaozhuangzhu; cout<<"shaozhuangzhu vs ermo"<<endl; pk(&shaozhuangzhu,&ermo); return 0; }
6、总结
函数重写只能发生在父类和子类之间
多态会根据实际对象的类型确定调用具体的函数
virtual关键字是c++中支持多态的唯一方式
被重写的虚函数可表现出多态的特性 - 静态联编
-
C++中多态的概念和意义
2019-06-26 10:45:11多态是面向对象理论当中的一个概念,它和具体的程序设计语言是没有关系的,也就是说多态指的仅仅是相同的行为方式,不同的行为结果; 这种多态的表现形式在 C++ 中由虚函数来实现; 更多C++相关知识体系,请移步 ... -
多态的概念和意义
2021-12-05 21:37:56面向对象中期望的行为: ...C++语言直接支持多态的概念 (1)通过使用virtual关键字对多态进行支持 (2)被virtual声明的函数被重写后具有多态性 (3)被virtual声明的函数叫做虚函数 实验编程:多态的初体验 #in -
多态的含义、多态的作用及多态的详细代码实现
2022-03-17 21:11:051.多态的含义 什么是多态,就是一个事物有多种形态,比如说是老师是老师,他也是人,也是丈夫或者妻子,或者光棍儿,这就阐述了多种形态。 -
多态基本概念及原理
2021-12-09 22:32:47多态的含义是“多种形式”,相当于一个公共接口;传入不同的对象会产生不同的行为; 多态满足条件: 1、有继承关系; 2、子类重写父类的子函数; 多态使用: 父类的指针或引用指向子类对象; 重写: 返回值 、... -
【C++】49.多态的概念和意义
2019-11-12 15:49:45C++直接支持多态的概念: 通过使用 virtual 关键字对多态进行支持。 被 virtual 声明的函数被重写后具有多态特性。 被 virtual 声明的函数叫做虚函数。 class Parent { public: virtual void ... -
C++深度解析(39)—多态的概念和意义
2019-09-10 08:39:40C++语言直接支持多态的概念 <ul><li>通过使用;"><strong>virtual</strong></span>关键字对多态进行支持 <li><strong>;">被virtual声明的函数被重写后具有多态特性 </span></strong> 被;"><strong>... -
49-多态的概念和意义
2020-09-09 13:19:59//父类中定义 (我们期望调用子类中的对象,因为p指针指向子类c) 二、多态的概念和意义 1)面向对象中期望的行为 - 根据实际的对象类型判断如何调用重写函数 - 父类指针(引用)指向 * 父类对象则调用父类中定义... -
49、多态的概念和意义
2019-09-09 16:55:401、函数重写回顾 父类中被重写的函数依然会继承给子类 子类中重写的函数将覆盖父类中的函数 通过作用域分辨符(::)可以访问到父类中的函数 Child c; Parent* p = &...2、多态的概念和... -
Java中运行时的多态的含义及其作用
2021-10-19 18:44:06Java中运行时的多态的含义及其作用 1.多态含义 同种类的多个对象,在接收到同一个消息时却产生了不同的反应和效果。 2.运行时多态的含义 使用父类引用指向子类对象,再调用某一父类中的方法时,不同的子类会表现出... -
多态 (多态的用处,意义,应用)
2020-07-03 02:38:55对象转型(多态) 1、一个基类的引用类型可以“指向”其子类的对象。 public class TestInstanceOf { public static void main(String[] args) { Animal a = new Animal("name"); Dog d = new Dog("dogName",... -
Java中多态的概念
2022-01-16 10:35:04Java中多态的概念 -
第49课多态的概念和意义
2020-02-28 13:22:28多态的概念和意义 面向对象中期望的行为: 根据实际的对象类型判断如何调用重写函数 父类指针(引用)指向 父类对象则调用父类中定义的函数 子类对象则调用子类中定义的重写函数 面向对象中的多态的概念 根据... -
第四十九课 多态的概念和意义
2022-05-11 19:09:31多态的概念和意义 -
多态的概述、使用及意义
2020-09-04 17:32:13多态的概述、使用及意义 多态的概念 • 多态主要指同一种事物表现出来的多种形态。 • 饮料:可乐、雪碧、红牛、脉动、… • 宠物:猫、狗、鸟、小强、鱼、… • 人:学生、教师、工人、保安、… • 图形:矩形、... -
java多态概念
2022-05-15 21:30:56java多态 -
JAVA多态的作用、概念及用法理解,持续更新ing
2021-08-07 19:41:27JAVA多态的概述及作用 战神三考:Why、What、How 1、为何用多态? 2、多态是什么? 3、多态怎么用? 1、为什么要用多态 1)提高了代码的维护性 (通过继承和实现来保证) 2)提高了代码的扩展性 (通过多态来保证) 3)... -
C++深度解析 多态的概念和意义 --- virtual,虚函数,静态联编,动态联编(48)
2019-01-07 10:40:13C++深度解析 多态的概念和意义 --- virtual,虚函数,静态联编,动态联编(48) 父类指针(引用)指向 父类对象则调用父类中定义的函数 子类对象则调用子类中定义的重写函数 p->print(); /... -
深入理解Java中多态的含义
2019-05-27 21:33:371.什么是多态 多态从字面上理解为,一类事物在不同的环境下以... 在 Java 及其他的编程语言中,多态是一种很重要的特性。它是面向对象编程 4 种特性(封装、继承、多态、抽象)其中一种。体现了面向对象编程同面... -
java封装 继承 多态 的概念和作用
2019-12-01 14:46:43一:概念 封装: 在java中,我们对类的封装,对方法的封装,在其他类中只需要调用这个类或者方法就行。 通俗点理解,我们在启动汽车的时候。汽车对里面的零件构造进行了封装,只要提供给我们一个钥匙口,我们只...