多态

多态

亡梦爱人 提交于 2020-03-14 15:23:07
在说多态之前,先看下以下代码: class Animal: pass class Dog(Animal): pass class Cat(Animal): pass a = Animal() b = Dog() c = Cat() print(isinstance(a, Animal)) # True print(isinstance(b, Dog)) # True print(isinstance(c, Cat)) # True print(isinstance(b, Animal)) # True print(isinstance(c, Animal)) # True print(isinstance(a, Dog)) # False print(isinstance(a, Cat)) # False # 结论:子类的对象可以是父类的类型之一,但父类的对象不能是子类类型 通过上面的例子,可以知道父类可以对应多种类型,这就叫多态 在项目中,我们会经常遇到存储图片的问题,图片的类型很多,如:.jpg .png .pdf等等 我们如何用多态进行管理呢?代码如下 class PictureFile: def __init__(self, filename): if not filename.endswith(self.ext): # 让父类可以访问不同子类的属性,这就是多态

多态及其实现方法

余生颓废 提交于 2020-03-14 15:22:28
多态按字面意思就是“多种形态“。在面向对象语言中,接口的多种不同实现方式即为多态。用一句比较通俗的话说;同一操作作用于不同的对象,可以产生不同的效果。 多态在生活中就像是同一个词语,用在不同的语境中,可以表达不同的意思。 例子:比如有动物(Animal)之类(Class),而且由动物继承出类别(Chicken)和类别够(Dog),并对同一源自类别动物(父类别)之一消息有不同的响应,如类别动物有“()”的动作,而类别鸡会“啼叫()”,类别狗会“吠叫()”,则称之为多态。 实现方法一般有:虚方法,抽象法,接口 来源: https://www.cnblogs.com/xyx960427/p/12491953.html

C++学习笔记--从虚函数说开去

。_饼干妹妹 提交于 2020-03-14 04:28:03
虚函数与纯虚函数 : 虚函数:在某基类中声明为virtual并在一个或多个派生类中被重新定义的成员函数,virtual 函数返回类型 函数名(参数表){函数体;} ,实现多态性, 通过指向派生类的基类指针或引用 ,访问派生类中同名覆盖成员函数。注意虚函数在基类中是有定义的,即便定义是空。 纯虚函数:在基类中是没有定义的,必须由派生类重定义实现,否则不能由对象进行调用。 看下面的例子: #include<iostream> using namespace std; class Cshape { public: void SetColor(int color){m_nColor=color;} virtual void Display(void){}; private: int m_nColor; }; class Crectangle:public Cshape{ //公有继承 public: }; void main() { Crectangle obRectangle; Cshape* pShape=&obRectangle; pShape->Display(); } 上面例子中,Display是虚函数,虽然是空定义,并且在派生类中没有重写该函数,但是上面的代码在编译阶段不会出错,而是在链接时出错,而如果将Display声明为纯虚函数,即 virtual void Display

浅谈对OOP的理解

坚强是说给别人听的谎言 提交于 2020-03-13 00:41:09
1.谈谈你对OOP的理解? OOP是面向对象编程,特征分别是封装、继承、多态、抽象。 封装:封装是指将对象信息状态通过访问权限修饰符隐藏在对象内部,不允许外部程序直接访问,如果外部程序要访问对象内部,可以调用内部提供的get或set方法。简单来说,封装就是要找出某一类事务的公性然后提取出来。 继承:子类继承了父类所有的成员方法和属性,并且可以拥有自己特性。继承解决了代码的重用问题 多态:多态存在的三个条件1.继承2.重写3.父类引用指向子类对象 多态的实现方式1.接口实现,继承父类方法重写,同一个类中进行重载 重载:多个同名函数同时存在,具有不同的参数个数/类型,返回值类型可以相同可 以不同,调用方法时通过传递给它们的不同参数个数和参数类型来决定具体使用哪个方法, 这就是多态性,存在于父类和子类、同类中 重写:1.参数列表必须完全与被重写的方法相同 2.返回的类型必须一直与被重写的方法的返回类型相同 3.访问修饰符的限制一定要大于被重写方法的访问修饰符 4.重写方法一定不能抛出新的检查异常或者比被重写方法申明更加宽泛的检查型异常 5.存在于父类和子类之间,方法被定义为final不能被重写。 抽象:如果一个类含有抽象方法,则称这个类为抽象类,抽象类必须在类前用abstract关键字修饰。因为抽象类中含有无具体实现的方法,所以不能用抽象类创建对象。

OOP 概述

不问归期 提交于 2020-03-13 00:28:34
面向对象程序设计基于四个基本概念:数据抽象、封装、继承和动态绑定。 类的基本思想是数据抽象和封装。 1 数据抽象 数据抽象是一种依赖于接口和实现分离的编程技术。类的接口包括用户所能执行的操作;类的实现则包括类的数据成员、负责接口实现的函数体以及定义类所需的各种私有函数。 2 封装 封装实现了类的接口和实现的分离。封装后的类隐藏了它的实现细节,也就是说,类的用户只能使用接口而无法访问实现部分。 3 继承 通过继承联系在一起的类构成一种层次关系。通常在层次关系的根部有一个基类,其他类则是直接或间接地从基类继承而来,这些继承得到的类称为派生类。基类负责定义在层次关系中所有类共同拥有的成员,而每个派生类定义各自特有的成员。 4 多态 多态性(polymorphisn)是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。 实现多态,有二种方式,覆盖,重载。 覆盖,是指子类重新定义父类的虚函数的做法。 重载,是指允许存在多个同名函数,而这些函数的参数表不同(或许参数个数不同,或许参数类型不同,或许两者都不同)。 其实,重载的概念并不属于“面向对象编程”,重载的实现是:编译器根据函数不同的参数表,对同名函数的名称做修饰,然后这些同名函数就成了不同的函数

Java---覆盖与多态(二)

天涯浪子 提交于 2020-03-12 17:11:43
多态的基础语法: 举例 Animal.java //动物类: 父类 public class Animal { //移动的方法 public void move ( ) { System . out . println ( "动物在移动" ) ; } } Dog.java //狗类: 子类 public class Dog extends Animal { //移动的方法(覆盖) public void move ( ) { System . out . println ( "狗在狂奔" ) ; } } Bird.java //鸟类: 子类 public class Bird { //移动的方法(覆盖) public void move ( ) { System . out . println ( "鸟在飞翔" ) ; } public void catchInsect ( ) { System . out . println ( "鸟儿在抓害虫" ) ; } } 测试类 public class Test { public static void main ( ) { Animal a1 = new Animal ( ) ; a1 . move ( ) ; Dog d1 = new Dog ( ) ; d1 . move ( ) ; Bird b1 = new Bird ( )

C++类的大小计算汇总

≯℡__Kan透↙ 提交于 2020-03-11 03:59:33
  C++中类涉及到虚函数成员、静态成员、虚继承、多继承、空类等。   类,作为一种类型定义,是没有大小可言的。   类的大小,指的是类的对象所占的大小。因此,用sizeof对一个类型名操作,得到的是具有该类型实体的大小。 类大小的计算,遵循结构体的对齐原则; 类的大小,与普通数据成员有关,与成员函数和静态成员无关。即普通成员函数、静态成员函数、静态数据成员、静态常量数据成员,均对类的大小无影响; 虚函数对类的大小有影响,是因为虚函数表指针带来的影响; 虚继承对类的大小有影响,是因为虚基表指针带来的影响; 静态数据成员之所以不计算在类的对象大小内,是因为类的静态数据成员被该类所有的对象所共享,并不属于具体哪个对象,静态数据成员定义在内存的全局区; 空类的大小( 类的大小为1 ),以及含有虚函数,虚继承,多继承是特殊情况; 计算涉及到内置类型的大小,以下所述结果是在64位gcc编译器下得到(int大小为4,指针大小为8); 一、简单情况的计算 #include<iostream> using namespace std; class base { public: base()=default; ~base()=default; private: static int a; int b; char c; }; int main() { base obj; cout<<sizeof

C++三大特性

青春壹個敷衍的年華 提交于 2020-03-10 23:58:03
封装继承和多态 封装:隐藏实现细节,使得代码模块化,封装就是把过程和数据包装,将客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操纵,对其他信息隐藏。 类继承是指C++提供来扩展和修改类的方法,类继承就是从已有的类中派生出新的类,派生类继承了基类的特性,同时可以添加自己的特性,继承又分为 单一继承 多重继承 菱形继承 多态是在具有继承关系的类对象中去调用某一虚函数时(使用基类的指针/引用去调用同一函数),产生了不同的行为,构成多态的条件有两个( 说白了就是通过指针/引用在不同时候调用同一函数可能调用的是不同的版本,多态是指接口的多种不同实现方式 ) 调用函数的对象必须是指针或者引用 被调用的函数必须是虚函数,且完成了虚函数的重写(不覆盖会调用派生类的函数吗?) 动态(类型)绑定/静态(类型)绑定 静态类型:对象在声明时的类型,其在编译时决定 动态类型:变量所指向内存中该对象的类型(通常指指针/引用所绑定对象的类型),在运行期决定 静态类型决定了某个函数能不能被调用,而动态类型则在动态绑定发生时决定调用该函数的哪个版本 如果不使用指针和引用,则静态类型和动态类型一定相同 静态绑定:也叫静态联编,绑定的是对象的静态类型,某特性(比如函数)依赖于对象的静态类型,发生在编译器 动态绑定:也叫动态联编,绑定的是对象的动态类型,某特性(比如函数)依赖于对象的动态类型

C++基于多态的职工管理系统

别等时光非礼了梦想. 提交于 2020-03-10 22:21:21
主模块(职工管理系统.cpp) #include using namespace std; #include "workerManger.h" #include "worker.h" #include "employee.h" #include "Boss.h" #include "Manager.h" int main() { //实例化一个管理者对象 智汇代理申请 WorkerManger wm; int choice = 0; while (true) { //调用成员函数显示菜单 wm.Show_Menu(); cout << "请输入您的选择:" << endl; cin >> choice; switch (choice) { case 0://退出 wm.ExitSystem(); break; case 1://增加 wm.Add_Emp(); break; case 2://显示 wm.Show_Emp(); break; case 3://删除 wm.Del_Emp(); break; case 4://修改 wm.Mod_Emp(); break; case 5://查找 wm.Find_Emp(); break; case 6://排序 wm.Sort_Emp(); break; case 7://清空 wm.Clean_File(); break;

C++学习(十五)—多态(一)

蓝咒 提交于 2020-03-10 00:22:19
多态 多态分类 静态多态:运算符重载 函数重载 动态多态:父子之间继承 + 虚函数 动态多态满足的条件 父类中有虚函数 子类重写父类的虚函数 父类的指针或者引用指向子类的对象 注意:子类重新实现父类中的虚函数,必须返回值、函数名、参数一致才称为重写 子类在做重写的时候,可以不加关键字virtual 多态原理 当父类中存在虚函数后,内部发生结构变化 多了指针 vfptr 虚函数表指针—指向 虚函数表 vftable 虚函数表内部记录着虚函数的地址 当子类发生重写后,会修改子类中的虚函数表中的函数地址,但是并不会影响父类中的虚函数表 # include <iostream> using namespace std ; // 空类的大小 1 class Animal { public : virtual void speak ( ) // 加上virtual关键字后 speak函数变为虚函数 { cout << "动物在说话" << endl ; } } ; class Cat : public Animal { public : void speak ( ) { cout << "小猫在说话" << endl ; } } ; // 静态联编 -- 地址早绑定 // 利用动态联编 -- 地址晚绑定 virtual // 多态满足的条件 // 1、父类中有虚函数 // 2