多态

C++虚函数

匿名 (未验证) 提交于 2019-12-03 00:22:01
众所周知,C++虚函数是一大难点,也是面试过程中必考部分。此次,从虚函数的相关概念、虚函数表、纯虚函数、再到虚继承等等跟虚函数相关部分,做一个比较细致的整理和复习。 虚函数 OOP的核心思想是多态性(polymorphism)。把具有继承关系的多个类型称为多态类型。引用或指针的静态类型与动态类型不同这一事实正是C++实现多态性的根本。 C++ 的多态实现即是通过虚函数。在C++中,基类将类型相关的函数与派生类不做改变直接继承的函数区别对待。对于某些函数,基类希望它的派生类各自定义适合自身的版本,此时基类就将这些函数声明为虚函数(virtual function)。 C++在使用基类的引用或指针调用一个虚函数成员函数时会执行动态绑定。因为只有直到运行时才能知道调用了那个版本的虚函数,所以 所有的虚函数必须有定义。 动态绑定只有当通过指针或引用调用虚函数时才会发生。 一旦某个函数被声明为虚函数,则在所有派生类中它都是虚函数。所以在派生类中可以再一次使用virtual指出,也可以不用。 如果某次函数调用使用了默认实参,则该实参值由本次调用的静态类型决定。换句话说,如果我们通过基类的引用或指针调用函数,则使用基类中定义的默认实参,即使实际运行的是派生类的函数版本也是如此。此时,传入派生类函数的将是基类函数定义的默认实参。 在某些情况下,我们希望对虚函数的调用不进行动态绑定

第18课 - 多态与继承 - 下

匿名 (未验证) 提交于 2019-12-03 00:22:01
第18课 - 多态与继承 - 下 Source Example 1: #include <iostream> /* run this program using the console pauser or add your own getch, system("pause") or input loop */ class Parent { public: virtual void func() { printf("Parent->"); printf("func()!\n"); } virtual void func(int i) { printf("Parent->"); printf("func(int i)!\n"); } virtual void func(int i, int j) { printf("Parent->"); printf("func(int i, int j)!\n"); } }; class Child : public Parent { public: virtual void func(int i) { printf("Child->"); printf("func(int i)!\n"); } virtual void func(int i, int j) { printf("Child->"); printf("func(int i, int

C与C++的区别

匿名 (未验证) 提交于 2019-12-03 00:21:02
本篇博客对C与C++的区别与联系进行了整理。并对一些校的知识点进行了扩展。 首先我们先来看一看C/C++的联系 C/C++的联系: C是C++的子集,C++兼容大部分的C语言的语法结构 C/C++的区别: 我们都知道C是面向过程的语言,而C++是面向对象 的语言。那 这里我们就要知道 什么是面向对象? 面向对象 是一种思想,是基于面向过程而言的,就是说面向对象是将功能等通过对象来实现,将功能封装进对象之中,让对象去实现具体的细节;这种思想是将数据作为第一位,而方法或者说是算法作为其次,这是对数据一种优化,操作起来更加的方便,简化了过程。面向对象有三大特征: 封装、继承、多态 ,其中 封装性 指的是隐藏了对象的属性和实现细节,仅对外提供公共的访问方式,这样就隔离了具体的变化,便于使用,提高了复用性和安全性。对于 继承性 ,就是两种事物间存在着一定的所属关系,那么继承的类就可以从被继承的类中获得一些属性和方法;这就提高了代码的复用性。继承是作为多态的前提的。 多态 是说父类或接口的引用指向了子类对象,这就提高了程序的扩展性,也就是说只要实现或继承了同一个接口或类,那么就可以使用父类中相应的方法,提高程序扩展性,但是多态有一点不好之处在于:父类引用不能访问子类中的成员。 特点: 1:将复杂的事情简单化。 2:面向对象将以前的过程中的执行者,变成了指挥者。 3

第二十一天:组合,多态,封装.....

匿名 (未验证) 提交于 2019-12-03 00:14:01
Ŀ¼ property 组合指的是一个对象中的属性,该属性的值指向的是另一个对象。 组合的目的和继承一样,为了减少代码冗余 class People: def __init__(self,name,age,sex): self.name=name self.age=age self.sex=sex class Teacher(People): def __init__(self,name,age,sex): super().__init__(name,age,sex) class Student(People): def __init__(self,name,age,sex): super().__init__(name,age,sex) class Date: def __init__(self,year,month,day): self.year=year self.month=month self.day=day def tell_birth(self): print(f''' ===出生年月日=== 年:{self.year} 月:{self.month} 日:{self.day}''') tea1=Teacher('tank',17,'male') date_obj=Date(2002,1,1) tea1.date=date_obj

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

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

重载(编译期多态),重写(运行时多态)

匿名 (未验证) 提交于 2019-12-02 23:57:01
重载可以在 编译期 确定调用的方法。 在 Class 文件内部,方法的符号引用是根据 方法名称 、 参数 来区分的,对编译器来说重载方法跟其他方法一样,都是不同的方法而已。 而 Java 的重载是根据 静态类型 来确定方法,所以可以在编译期就能指定调用的方法。 静态类型 & 实际类型: 如, SuperClass obj = new SubClass(); 语句中,前面的「 SuperClass 」是 静态类型 ,后面的「 SubClass 」是 实际类型 。 变量的静态类型是不可变的,编译时可知的,但是实际类型是运行时才能确定。 例: public static void main ( String [] args ) { B b = new B (); f ( b ); // b A c = new C (); f ( c ); // 静态类型是A,所以输出a } static void f ( C c ) { System . out . println ( "c" ); } static void f ( B b ) { System . out . println ( "b" ); } static void f ( A a ) { System . out . println ( "a" ); } static class A {} static class B

父类作为方法形参实现多态(父类作为返回值)待加

匿名 (未验证) 提交于 2019-12-02 23:49:02
宠物类 package com.pangui; //父类 public class CongWu { private String name = "无名氏"; private int health ; private int love; // public CongWu() { // //无参构造方法 // } public CongWu(String name,int health,int love) { //带参构造方法 this.name = name; if(health < 0||health > 100) { //System.out.println("健康值应在0-100之间,默认值为60"); this.health = 60; }else { this.health = health; } if(love>100||love<0) { //System.out.println("请密度应在0-100之间,默认值为60"); this.love = 60; }else { this.love = love; } // this.health = health; // this.love = love; } //无参构造方法和有参构造方法的作用?????????????????? public String getName() { return name; }

利用多态特性,创建一个手机类Phones,定义打电话的方式call,创建三个子类,并在各自的方法中重写方法,编写程序入口main()方法,实现多种手机打电话

匿名 (未验证) 提交于 2019-12-02 23:49:02
|--需求说明 利用多态特性,创建一个手机类Phones,定义打电话的方式call,创建三个子类,并在各自的方法中重写方法,编写程序入口main()方法,实现两种手机打电话 |--解题思路 采用简单工厂模式, 设计四个角色: 工厂类、抽象产品类、具体产品类 由一个工厂类,根据客户传入的参数来决定创建/生产哪一种具体产品。 |--代码内容 1 //这个Phones类是一个抽象类 2 public abstract class Phones { 3 //定义一个抽象方法,call,用来被不同的类继承 4 public abstract void call(); 5 } 抽象产品类---Phones 1 public class IPone extends Phones{ 2 //重写父类的call方法,用来实现具体的苹果手机打电话 3 @Override 4 public void call() { 5 System.out.println("苹果手机打电话"); 6 } 7 } 具体产品类----Iphone 1 public class APhone extends Phones { 2 //重写父类的call方法,用来实现具体的安卓手机打电话 3 @Override 4 public void call() { 5 System.out.println("安卓手机打电话"); 6