多态

java多态的实现机制

南楼画角 提交于 2019-12-04 04:17:53
Java提供了编译时多态和运行时多态两种多态机制。前者是通过方法重载实现的,后者是通过方法的覆盖实现的。   在方法覆盖中,子类可以覆盖父类的方法,因此同类的方法会在父类与子类中有着不同的表现形式。  在Java语言中,基类的引用变量不仅可以指向基类的实例对象,也可以指向其子类中的实例对象。同样,接口中的引用变量也可以指向其实现类的实例对象。而程序调用的方法在运行时期才动态绑定(绑定是指将一个方法调用和一个方法主体联系在一起),绑定的是引用变量所指向的具体实例对象的方法,也就是内存中正在运行的那个对象的方法,而不是引用变量的类型中定义的方法。通过这种动态绑定实现了多态。由于只有在运行时才能确定调用哪个方法,因此通过方法覆盖实现的多态也可以被称为运行时多态。      示例一: 1 public class Base { 2 public Base(){ 3 g(); 4 } 5 6 public void g() { 7 System.out.println("Base g()"); 8 } 9 10 public void f() {11 System.out.println("Base f()");12 }13 } 1 public class Derived extends Base{ 2 3 public void g() { 4 System.out.println(

C++面向对象 继承与多态

不打扰是莪最后的温柔 提交于 2019-12-04 04:00:22
第十三章 多态与继承性 13.1继承与派生 1. 继承与派生的语法格式: Class 派生类名:继承方法 基类类名 { //新增的属性和行为 基类成员的覆盖或者重载 } 2. 继承方法有公开继承、保护继承和私有继承。三种继承方式分别用public, protected和private.无论哪种方式,派生类都全部继承了基类的一切成员(基类的构造函数、拷贝构造函数和析构函数除外) 3. 派生类型的访问属性:基类的私有成员在派生类当中是存在的,但是被隔离起来,不能直接访问。如果要访问他们需要通过基类的成员函数。 4. 派生类的对象可以初始化(拷贝构造)基类的对象、初始化基类的引用、赋值给基类的对象。派生类对象的地址可以初始化基类的指针变量,可以赋值给基类的指针变量。 5. 虚函数:使用保留字virtual可以将成员函数声明为虚函数。 6. 友元函数不能是虚函数! 7. 可能作为基类的类应该定义他的析构函数为虚函数(比较好) 8. 纯虚函数(在函数首部之后,写下记号“=0”之后虚函数就是纯虚函数) 9. 只要一个类含有纯虚函数,那这个类就是抽象类。抽象类的唯一作用就是被继承。派生类当中可以覆盖定义基类的纯虚函数。抽象类的派生类也可能是抽象类,只要它当中还有纯虚函数没有被覆盖定义。当一个类中没有纯虚函数的时候,这个类便成为具体类。 10. 不能创建抽象类的对象

java:多态

╄→尐↘猪︶ㄣ 提交于 2019-12-04 02:00:37
多态中访问成员变量的两种方法:   1:直接通过对象名称访问成员变量,等号左边是谁,就优先用谁,没有则向上查找   2:间接通过成员方法访问成员变量,方法属于谁,就优先用谁,没有则向上查找 多态中访问成员方法的规则:   看new的是谁,就优先用谁,没有则向上查找 口诀:成员变量,编译看左边,运行还看左边    成员方法,编译看左边,运行看右边 来源: https://www.cnblogs.com/BatmanY/p/11827636.html

Java面向对象

Deadly 提交于 2019-12-03 23:42:20
该系列博文会告诉你如何从入门到进阶,一步步地学习Java基础知识,并上手进行实战,接着了解每个Java知识点背后的实现原理,更完整地了解整个Java技术体系,形成自己的知识框架。 概述: Java是面向对象的程序设计语言,Java语言提供了定义类、成员变量、方法等最基本的功能。类可被认为是一种自定义的数据类型,可以使用类来定义变量,所有使用类定义的变量都是引用变量,它们将会引用到类的对象。类用于描述客观世界里某一类对象的共同特征,而对象则是类的具体存在,Java程序使用类的构造器来创建该类的对象。 对象和类: Java是面向对象的程序设计语言,类是面向对象的重要内容,可以把类当成一种自定义类型,可以使用类来定义变量,这种类型的变量统称为引用变量。也就是说,所有类是引用类型。对象是由类创建出来的,可以说类时对象的抽象,对象是类的实例。 对象的概念: Java 是面向对象的编程语言,对象就是面向对象程序设计的核心。所谓对象就是真实世界中的实体,对象与实体是一一对应的,也就是说现实世界中每一个实体都是一个对象,它是一种具体的概念。对象有以下特点: 对象具有属性和行为。 对象具有变化的状态。 对象具有唯一性。 对象都是某个类别的实例。 一切皆为对象,真实世界中的所有事物都可以视为对象。 面向对象与面向过程: 1、面向过程: 面向过程是一种以事件为中心的编程思想

c++虚函数的原理及实现

梦想的初衷 提交于 2019-12-03 22:09:02
虚函数是在类中被声明为virtual的成员函数,当编译器看到通过指针或引用调用此类函数时,对其执行晚绑定,即通过指针(或引用)指向的类的类型信息来决定该函数是哪个类的。通常此类指针或引用都声明为基类的,它可以指向基类或派生类的对象。 多态指同一个方法根据其所属的不同对象可以有不同的行为(根据自己理解,不知这么说是否严谨)。 举个例子说明虚函数、多态、早绑定和晚绑定: 李氏两兄妹(哥哥和妹妹)参加姓氏运动会(不同姓氏组队参加),哥哥男子项目比赛,妹妹参加女子项目比赛,开幕式有一个参赛队伍代表发言仪式,兄妹俩都想 去露露脸,可只能一人去,最终他们决定到时抓阄决定,而组委会也不反对,它才不关心是哥哥还是妹妹来发言,只要派一个姓李的来说两句话就行。运动会如期举 行,妹妹抓阄获得代表李家发言的机会,哥哥参加了男子项目比赛,妹妹参加了女子项目比赛。比赛结果就不是我们关心的了。 现在让我们来做个类比(只讨论与运动会相关的话题): (1)类的设计: 李氏兄妹属于李氏家族,李氏是基类(这里还是抽象的纯基类),李氏又派生出两个子类(李氏男和李氏女),李氏男会所有男子项目的比赛(李氏男的成员函 数),李氏女会所有女子项目的比赛(李氏女的成员函数)。姓李的人都会发言(基类虚函数),李氏男和李氏女继承自李氏当然也会发言,只是男女说话声音不一 样,内容也会又差异,给人感觉不同

C++中虚函数实现原理揭秘

不羁岁月 提交于 2019-12-03 22:08:47
编译器到底做了什么实现的虚函数的晚绑定呢?我们来探个究竟。 编译器对每个包含虚函数的类创建一个表(称为V TA B L E)。在V TA B LE中,编译器放置特定类的虚函数地址。在每个带有虚函数的类 中,编译器秘密地置一指针,称为v p o i n t e r(缩写为V PT R),指向这个对象的V TA B L E。通过基类指针做虚函数调用时(也就是做多态调用时),编译器静态地插入取得这个V P TR,并在V TA B L E表中查找函数地址的代码,这样就能调用正确的函数使晚捆绑发生。为每个类设置V TA B L E、初始化V PTR、为虚函数调用插入代码,所有这些都是自动发生的,所以我们不必担心这些。利用虚函数,这个对象的合适的函数就能被调用,哪怕在编译器还不知道这个对象的特定类型的情况下。(《C++编程思想》) 在任何类中不存在显示的类型信息,可对象中必须存放类信息,否则类型不可能在运行时建立。那这个类信息是什么呢?我们来看下面几个类: class no_virtual { public: void fun1() const{} int fun2() const { return a; } private: int a; } class one_virtual { public: virtual void fun1() const{} int fun2() const {

动态多态的原理

时间秒杀一切 提交于 2019-12-03 22:07:31
多态的三个条件:1.继承,2.虚函数重写,3.父类指针或引用指向子类对象 什么是多态?相同对象收到不同消息或不同对象收到相同消息时产生的不同动作。 首先是多态的分类,分为静态多态和动态多态,也可以称为早绑定和晚绑定,区分的时刻就是程序在编译阶段根据参数个数确定调用哪个函数,如果能够确定就是早绑定如果不能确定就是晚绑定,如果要实现多态就必须要使用虚函数。 从编译角度看: c++编译器在编译的时候,要确定每个对象调用的函数(非虚函数)的地址称为早期绑定,当我们将子类的对象son的地址赋给父类变量时,c++编译器进行了类型转换,此时c++编译器认为父类变量保存的就是父类对象的地址,当在main函数中执行父类变量的方法时,调用的当然就是父类对象的函数。 从内存角度看: 我们构造子类的对象时,首先要调用父类的构造函数去构造父类的对象,然后才调用子类的构造函数完成自身部分的构造,从而拼接出一个完整的子类对象。当我们将子类对象转换为父类型时,该对象就被认为是原对象整个内存模型的上半部分,那么当利用类型转换后的对象指针去调用它的方法时,当然也就是调用它所在的内存中的方法。   正如很多人那么认为,父类变量指向的是子类的对象,如果希望输出的是子类的方法,就要用到虚函数了。   前面输出的结果是因为编译器在编译的时候,就已经确定了对象调用的函数的地址,要解决这个问题就要使用晚绑定

多态基本语法和原理

筅森魡賤 提交于 2019-12-03 22:04:51
多态(多种形态)是C++面向对象的三大特性之一 多态分为两类: 1.静态多态: 函数重载和运算符重载属于静态多态,复用函数名 2.动态多态 :派生类和虚函数实现运行时多态 (重点) 静态多态和动态多态的区别: 1.静态多态的函数地址早绑定—编译阶段确定函数地址 2.动态多态函数地址晚绑定—运行阶段确定函数地址 3. 父类的指针或引用指向子类 ,满足子类实现虚函数的功能 动态多态满足条件: 1.有继承关系 2.子类要重写父类的虚函数 重写 :即函数返回值类型 函数名 参数列表 完全相同 //动态多态的使用 父类的指针或者引用,指向子类对象 */ # include "pch.h" # include <iostream> using namespace std ; class animal { public : virtual void speak ( ) { cout << "动物在说话" << endl ; } } ; class cat : public animal { public : //重写:即函数返回值类型 函数名 参数列表 完全相同 void speak ( ) { cout << "小猫在说话" << endl ; } } ; class dog : public animal { public : void speak ( ) { cout << "小狗在说话"

C++ 之虚函数的实现原理

拜拜、爱过 提交于 2019-12-03 22:04:34
c++的多态使用虚函数实现,通过“晚绑定”,使程序在运行的时候,根据对象的类型去执行对应的虚函数。 C++ 之虚函数的实现原理 带有虚函数的类,编译器会为其额外分配一个虚函数表,里面记录的使虚函数的地址,当此类被继承时,子类如果也写了虚函数就在子类的虚函数表中将父类的函数地址覆盖,否则继承父类的虚函数地址。 实例化之后,对象有一个虚函数指针,虚函数指针指向虚函数表,这样程序运行的时候,通过虚函数指针找到的虚函数表就是根据对象的类型来指向的了。 转载于:https://www.cnblogs.com/bewolf/p/9352116.html 来源: CSDN 作者: weixin_30567225 链接: https://blog.csdn.net/weixin_30567225/article/details/97549743

C++虚函数的原理及实现

百般思念 提交于 2019-12-03 22:04:19
虚函数是在类中被声明为virtual的成员函数,当编译器看到通过指针或引用调用此类函数时,对其执行晚绑定,即通过指针(或引用)指向的类的类型信息来决定该函数是哪个类的。通常此类指针或引用都声明为基类的,它可以指向基类或派生类的对象。 多态指同一个方法根据其所属的不同对象可以有不同的行为(根据自己理解,不知这么说是否严谨)。 举个例子说明虚函数、多态、早绑定和晚绑定: 李氏两兄妹(哥哥和妹妹)参加姓氏运动会(不同姓氏组队参加),哥哥男子项目比赛,妹妹参加女子项目比赛,开幕式有一个参赛队伍代表发言仪式,兄妹俩都想 去露露脸,可只能一人去,最终他们决定到时抓阄决定,而组委会也不反对,它才不关心是哥哥还是妹妹来发言,只要派一个姓李的来说两句话就行。运动会如期举 行,妹妹抓阄获得代表李家发言的机会,哥哥参加了男子项目比赛,妹妹参加了女子项目比赛。比赛结果就不是我们关心的了。 现在让我们来做个类比(只讨论与运动会相关的话题): (1)类的设计: 李氏兄妹属于李氏家族,李氏是基类(这里还是抽象的纯基类),李氏又派生出两个子类(李氏男和李氏女),李氏男会所有男子项目的比赛(李氏男的成员函 数),李氏女会所有女子项目的比赛(李氏女的成员函数)。姓李的人都会发言(基类虚函数),李氏男和李氏女继承自李氏当然也会发言,只是男女说话声音不一 样,内容也会又差异,给人感觉不同