多态

面向对象的三个基本特征是:封装、继承、多态

…衆ロ難τιáo~ 提交于 2019-11-29 23:00:27
封装 封装最好理解了。封装是面向对象的特征之一,是对象和类概念的主要特性。 封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。 继承 面向对象编程 (OOP) 语言的一个主要功能就是“继承”。继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。 通过继承创建的新类称为“子类”或“派生类”。 被继承的类称为“基类”、“父类”或“超类”。 继承的过程,就是从一般到特殊的过程。 要实现继承,可以通过“继承”(Inheritance)和“组合”(Composition)来实现。 在某些 OOP 语言中,一个子类可以继承多个基类。但是一般情况下,一个子类只能有一个基类,要实现多重继承,可以通过多级继承来实现。 继承概念的实现方式有三类:实现继承、接口继承和可视继承。 Ø 实现继承是指使用基类的属性和方法而无需额外编码的能力; Ø 接口继承是指仅使用属性和方法的名称、但是子类必须提供实现的能力; Ø 可视继承是指子窗体(类)使用基窗体(类)的外观和实现代码的能力。 在考虑使用继承时,有一点需要注意,那就是两个类之间的关系应该是“属于”关系。例如,Employee 是一个人,Manager 也是一个人,因此这两个类都可以继承 Person 类。但是 Leg 类却不能继承

C++对象模型:单继承,多继承,虚继承,菱形虚继承,及其内存布局图

放肆的年华 提交于 2019-11-29 22:02:48
C++目前使用的对象模型: 此模型下, nonstatic数据成员被置于每一个类的对象中 ,而 static数据成员则被置于类对象之外 , static和nonstatic函数也都放在类对象之外(通过函数指针指向) ,而 对于virtual函数,则通过虚函数表+虚函数指针来支持 : 1)每个类生成一个表格,称为 虚表 (virtual table,简称vtbl),虚函数表中存在一堆指针,这些指针指向该类的每一个虚函数,虚表中的函数地址按照声明时的顺序排列 2)每个类对象都有一个 虚表指针 (简称vptr),由编译器为其生成,虚表指针的设定和重置皆由类的相关函数控制(构造函数,析构函数,赋值操作符),虚表指针vptr的位置由编译器决定,一般编译器把vptr放在一个类对象的最前端(也就是说对象的地址就是vptr的地址) 3)虚函数表的前面设置了一个指向type-info的指针,用以支持RTTI(Run Time Type Identification,运行时类型识别),RTTI是为支持多态生成的信息,包括对象的继承关系,对象本身的描述等,只有具有虚函数的对象才会生成 样例: class Base { public: Base(int i) :baseI(i){}; int getI(){ return baseI; } static void countI(){}; virtual

c/c++常见面试题(一)

佐手、 提交于 2019-11-29 21:39:57
0.static、const、volatile的作用和区别 static: https://www.cnblogs.com/Manual-Linux/p/8870038.html 第一 、在修饰变量的时候,static修饰的静态局部变量只执行一次,之后再初始化无效。而且延长了局部变量的生命周期,直到程序运行结束以后才释放。 第二 、static修饰全局变量的时候,这个全局变量只能在本文件中访问,不能在其它文件中访问,即便是extern外部声明也不可以。 第三 、static修饰一个函数,则这个函数的只能在本文件中调用,不能被其他文件调用。Static修饰的局部变量存放在全局数据区的静态变量区。初始化的时候自动初始化为0 const: 1.修饰的变量只读,不可改变 2.防止意外修改,减少bug 3.可以节省空间,避免不必要的 内存分配 volatile: 告诉编译器这个变量随时可变,不需要优化 1.请问全局变量和局部变量能否重名 能,局部会屏蔽全局。要用全局变量,需要使用"::" 2. 用三目运算符(X)>(Y)?(X):(Y)宏定义实现比较两个数的大小 #define MAX(X, Y) ((X)>(Y)?(X):(Y)) 3.malloc的了解 malloc是动态内存分配,是用户动态申请系统分配指定字节的内存块的函数。返回类型是 void* 类型 对应free,

Python 之 面向对象

喜欢而已 提交于 2019-11-29 19:36:41
Python 之 面向对象 类、对象定义及使用 属性和方法 属性 方法 构造方法 封装 继承 多态 本篇文章重点讲解Python的面向对象,包括Python中如何定义类、对象、封装、继承、多态等 类、对象定义及使用 定义类: 语法 class 类名(父类): 代码块 注意:()可有可无 eg: class Person: #这是一个类 创建对象(实例): 语法 对象名=类名() 注意:Java语言在实例化对象是,采用new关键字,而Python语言不需要。 eg: person=Person() isinstance()语法 isinstance()是检测一个对象是否是一个类的实例 语法格式: isinstance(对象,类),结果返回True和False eg: isinstance(person,Person),结果为True 属性和方法 属性 属性:分为类属性和对象属性 属性修饰符:私有属性、公共属性 类属性 class Person: name="张三" #name是类属性 对象属性 p1=Person() p1.name="张三" #name是对象属性 类属性和对象属性的区别? 类属性直接通过类名就可以调用,比如: Person.name 对象属性必须通过对象名调用,比如: person.name 公共属性 没有任何修饰符,该类型的属性可以被任意一个对象所调用 比如:

c++多态实现与虚函数

血红的双手。 提交于 2019-11-29 19:32:59
#include <stdlib.h> #include <stdio.h> #include <iostream> #include <bitset> using namespace std; //如果delete后边跟父类的指针则只会执行父类的析构函数,如果delete后面跟的是子类的指针,那么它即会执行子类的析构函数,也会执行父类的析构函数 //virtual在函数中的使用限制 // 普通函数不能是虚函数,也就是说这个函数必须是某一个类的成员函数,不可以是一个全局函数,否则会导致编译错误。 // 静态成员函数不能是虚函数 static成员函数是和类同生共处的,他不属于任何对象,使用virtual也将导致错误。 // 内联函数不能是虚函数 如果修饰内联函数 如果内联函数被virtual修饰,计算机会忽略inline使它变成存粹的虚函数。 // 构造函数不能是虚函数,否则会出现编译错误。 //将父类的的析构函数设置成虚函数,这样父类指针指向的是哪个对象,哪个对象的构造函数就会先执行,然后执行父类的构造函数。销毁的时候子类的析构函数也会执行。 class A { private: int m; public: void first() { printf("A1\n"); } virtual void second() { printf("A2\n"); } A(const A&

组合&多态&封装

孤者浪人 提交于 2019-11-29 19:18:55
组合&多态&封装 一、组合 1.1什么是组合 对象的属性是另一个对象 class Foo: pass class Bar: pass f = Foo() f.bar = Bar() 1.2 为什么要用组合 减少代码冗余 1.3 如何使用组合 首先我们有老师类和学生类,他们都有共同的属性,课程姓名,课程价格,课程时间,为了避免代码冗余,我们就需要用组合。 #这样的代码,我们看起来是不是和繁琐,那我们就把他们相同的属性拿出来,重新定义一个类,用的时候,我们就直接传入这个对象就好了。 class Person: #定义一个基类 school = 'oldboy' class Teacher(Person): def __init__(self,name,age,level,course_name,course_price,course_time): self.name = name self.age = age self.level = level self.course_name = course_name self.course_price = course_price self.course_time = course_time class Student(Person): def __init__(self, name, age, level, course_name,

C++构造函数和析构函数调用虚函数时都不会使用动态联编

六眼飞鱼酱① 提交于 2019-11-29 17:11:05
可以,虚函数底层实现原理(但是最好不要在构造和析构函数中调用) 可以,但是没有动态绑定的效果,父类构造函数中调用的仍然是父类版本的函数,子类中调用的仍然是子类版本的函数。 effictive c++第九条,绝不在构造和析构过程中调用virtual,因为构造函数中的base的虚函数不会下降到derived上。而是直接调用base类的虚函数。绝不在构造和析构函数中调用virtual函数: a) 如果有继承,构造函数会先调用父类构造函数,而如果构造函数中有虚函数,此时子类还没有构造,所以此时的对象还是父类的,不会触发多态。更容易记的是基类构造期间,virtual函数不是virtual函数。 b) 析构函数也是一样,子类先进行析构,这时,如果有virtual函数的话,子类的内容已经被析构了,C++会视其父类,执行父类的virtual函数。 c) 总之,在构造和析构函数中,不要用虚函数。如果必须用,那么分离出一个Init函数和一个close函数,实现相关功能即可。 原文链接:https://blog.csdn.net/chen134225/article/details/81564972 第一个理由是概念上的。 在概念上,构造函数的工作是生成一个对象。在任何构造函数中,可能只是部分形成对象——我们只能知道基类已被初始化,但并不能知道哪个类是从这个基类继承来的。然而,虚函数在继承层次上是“向前

类和对象

落花浮王杯 提交于 2019-11-29 16:37:24
类和对象 面向对象概述 所谓对象就是某种事物的抽象(功能),抽象包括数据抽象和过程抽象两个方面,数据抽象就是定义对象的属性;过程抽象就是定义对象的操作(行为)。 面向对象的三(四)大特征:封装,继承,多态,(抽象)。 封装 :把描述对象属性的变量及实现对象功能的方法结合起来,定义一个程序单位,并保证外界不能任意 更改内部的属性,不能任意调动内部的方法接口。 继承 :大大增强了代码的可复用性,提高了软件的开发效率,为程序的修改扩充提供了材料。Java 不支持多继 承(菱形继承方式),为了弥补 Java 不支持继承带来的子类不能享用多个父类的成员缺憾,我们在后面的学习中会 引入“接口”这个概念。 多态 :同一个方法名,根据被调对象的不同,实现了不同的行为。 主要分成静多态(方法的重载)和动多态(继承,重写,向上造型)。 抽象 :使用了关键词abstract声明的类叫作“抽象类”。如果一个类里包含了一个或多个抽象方法,类就必须指定成abstract(抽象)。“抽象方法”,属于一种不完整的方法,只含有一个声明,没有方法主体。 类和对象概述 1. 类的概念 类是一种 新的数据类型 ,类定义数据类型的属性(变量,字段),行为(方法)。对象是基于类的具体实现,又称为类的实例。 类是一个抽象概念 , 对象是类的具体实现 类所定义的对象是不唯一的,依需求(需要)而定 例: 定义一个类,人

Thinking In Java 4th Chap8 多态(未完)

こ雲淡風輕ζ 提交于 2019-11-29 16:28:22
多态的意义:改善代码的可读性并且使得程序“可扩展” 多态方法调用允许一种类型表现出与其他相似类型之间的"区别",基于方法的行为不同而表现出来 将一个方法调用同一个方法主体关联起来称作绑定,程序执行前绑定称为 前期绑定, 运行时根据对象的类型进行绑定称为 后期绑定 。   Java中除了static和final(包括private)方法,都采用后期绑定。 向上转型可以表现为此语句:(在调用方法时总是会进行正确的调用,也即调用正确的子类的方法)   (Shape类是Circle类的基类) Shape s = new Circle();    调用方法:s.draw();(draw()方法已经在Circle类中被覆写)实际上调用的还是 Circle.draw() ,虽然对象s被声明为Shape(但是指向Circle类的引用) 1 package Music; 2 enum Note{ 3 MIDDLE_C,C_SHARP,B_FLAT 4 } 5 class Instrument{ 6 void play(Note n) { 7 System.out.print("Instrument.play()" + n); 8 } 9 }; 10 class Percussion extends Instrument{ 11 void play(Note n) { 12 System.out