12-继承与多态(下)

一.重写与重载

   

class Parent
	{
	public:
		virtual  void func()
		{
			cout<<" void func()"<<endl;
		}
		virtual void func(int i)
		{
			cout<<" void func(int i)"<<endl;
		}
		virtual void func(int i,int j)
		{
			cout<<" void func(int i,int j)"<<endl;
		}
	};

class Child:public Parent
{
public:
	virtual void func(int a,int b)
	{
		cout<<" void func(int a,int b)"<<endl;
	}
	virtual void func(int i,int j,int k)
	{
		cout<<" void func(int i,int j,int k)"<<endl;
	}
};

   
函数重载:

           (1)必须在同一类中,也就是在同一个作用域中。

           (2)
子类无法重载父类的函数,父类同名函数被覆盖

              如: c.func();//错误,编译不过 

           (3)重载是在编译期间根据参数类型和个数决定调用函数的

    函数重写:

(1) 必须发生在父类与子类之间

            (2)
并且父类与子类中的函数必须有完全相同的原型。

            (3)
使用 virtual 声明之后能顾产生多态

            (4)
多态是在运行期间根据具体对象的类型决定调用函数的

    对比:
一个是在编译期间决定的,一个是在运行期间决定的,所以重载的效率还是比重写的效率高。

 

二. 对虚函数的理解

     C++中多态的实现原理

         (1)
当类中声明虚函数时,编译器会在类中生成一个虚函数表

         (2)
 虚函数表是一个存储类成员函数指针的数据结构

         (3)
 虚函数表是由编译器自动生成与维护的

         (4)  virtual 成员函数会被编译器放入虚函数表中

         (5)
存在虚函数时,每个对象中都有一个指向虚函数表的指针。     

 

void run(Parent* p)
{
	p->func(1,2);
}

               通过虚函数表指针VPTR调用重写函数是在程序运行时进行的,因此需要通过寻址操作才能确        定真正的应该调用的函数。而普通成员函数是在编译时就确定了调用的函数。在效率上,虚函数
           的效率要低的多。

    注意:
处于效率的考虑,没有必要把所有的成员函数都声明为虚函数。

   对象中VPTR指针什么时候被初始化的?

        (1)
对象在创建的时候由编译器对VPTR指针进行初始化,

        (2)
只有当对象的构造完全结束后VPTR的指向才最终确定

        (3)
父类对象的VPTR指向父类虚函数表

        (4)
子类对象的VPTR指向子类虚函数表

class Parent
{
public:
	Parent()
	{
		this->func();
	}
	virtual void func()
	{
		cout<<"virtual void Parent::func()"<<endl;
	}
};

class Child:public Parent
{
public:
	Child()
	{
		func();
	}
	void func()
	{
		cout<<"void Child::func()"<<endl;
	}
};

int main()
{
	Child p;
	p.func();
	return 0;
}

     结论: 构造函数中调用虚函数无法实现多态

三. 纯虚函数

   
 面向对象的抽象类

         (1) 抽象类可用于表示现实世界中的抽象概念

         (2) 抽象类是一种只能定义类型,而不能产生对象的类

         (3) 抽象类只能被继承并重写相关函数

         (4) 抽象类的直接特征是纯虚函数

      说明: 纯虚函数只声明函数原型,不定义函数体的虚函数。

    抽象类与纯虚函数

         
(1) 抽象类不能用于定义对象

          (2) 抽象类只能用于定义指针和引用

          (3) 抽象中的纯虚函数必须被子类重写

class Shape
{
public:
	virtual double area()=0;
};

area是纯虚函数, =0 告诉编译器这个函数故意只声明不定义。

class Shape
{
public:
    virtual double area() = 0;
};

class Rectangle : public Shape
{
    double m_a;
    double m_b;
public:
    Rectangle(double a, double b)
    {
        m_a = a;
        m_b = b;
    }

    double area()
    {
        return m_a * m_b;
    }
};

class Circle : public Shape
{
    double m_r;
public:
    Circle(double r)
    {
        m_r = r;
    }

    double area()
    {
        return 3.14 * m_r * m_r;
    }
};

void area(Shape* s)
{
    cout<<s->area()<<endl;
}

int main(int argc, char *argv[])
{
    Rectangle rect(2, 3);
    Circle circle(4);

    area(&rect);
    area(&circle);
 	return 0;
}

小结:

     
(1) 函数重载与函数重写不同

      (2) 多态是通过虚函数实现的

      (3) 虚函数在效率上会有影响

      (4) 抽象类是通过纯虚函数实现的。     

时间: 2024-08-28 14:34:17

12-继承与多态(下)的相关文章

Java学习笔记--继承和多态(下)

1.通过继承来开发超类(superclass) 2.使用super 关键词唤起超类的构造方法 3.在超类中覆盖方法 4.区分override和overload 5.在Object类中探索toString()类 6.发现多态性和动态绑定 7.描述解释为什么向下转型是必须的 8.在Object类中探索equals 方法 9.存储,取回,实现ArrayList的对象 10.使用ArrayList类实现Stack 11.超类中使用数据和方法,protected 12.使用final模块来禁止类和方法的覆

PHP面向对象的三大特征操作——封装、继承、多态(下)

<?php 继承(单继承)特点:一个子类只有一个父类,一个父类可以有多个子类.//父类(基类)class Ren{    public $name;    public function say(){        echo "问候:";    }    }//子类(派生类)可以继承父类的一切class China extends Ren{    public function say(){        parent::say();        echo "最近怎么

《Java从小白到大牛》之第12章 继承与多态

<Java从小白到大牛>纸质版已经上架了!!! 类的继承性是面向对象语言的基本特性,多态性前提是继承性.Java支持继承性和多态性.这一章讨论Java继承性和多态性. Java中的继承 {#java} 为了了解继承性,先看这样一个场景:一位面向对象的程序员小赵,在编程过程中需要描述和处理个人信息,于是定义了类Person,如下所示: //Person.java文件 package com.a51work6; import java.util.Date; public class Person

JavaScript 面向对象程序设计(下)&mdash;&mdash;继承与多态 【转】

JavaScript 面向对象程序设计(下)--继承与多态 前面我们讨论了如何在 JavaScript 语言中实现对私有实例成员.公有实例成员.私有静态成员.公有静态成员和静态类的封装.这次我们来讨论一下面向对象程序设计中的另外两个要素:继承与多态. 1 又是几个基本概念 为什么要说又呢? 在讨论继承时,我们已经列出了一些基本概念了,那些概念是跟封装密切相关的概念,今天我们要讨论的基本概念,主要是跟继承与多态相关的,但是它们跟封装也有一些联系. 1.1 定义和赋值 变量定义是指用 var a;

2、C#面向对象:封装、继承、多态、String、集合、文件(上)

面向对象封装 一.面向对象概念 面向过程:面向的是完成一件事情的过程,强调的是完成这件事情的动作. 面向对象:找个对象帮你完成这件事情. 二.面向对象封装 把方法进行封装,隐藏实现细节,外部直接调用. 打包,便于管理,为了解决大型项目的维护与管理. 三.什么是类? 将相同的属性和相同方法的对象进行封装,抽象出 “类”,用来确定对象具有的属性和方法. 类.对象关系:人是类,张三是人类的对象. 类是抽象的,对象是具体的.对象可以叫做类的实例,类是不站内存的,对象才占内存. 字段是类的状态,方法是类执

JAVA基础——面向对象三大特性:封装、继承、多态

JAVA面向对象三大特性详解 一.封装 1.概念: 将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问. 2.好处: 只能通过规定的方法访问数据.     隐藏类的实例细节,方便修改和实现. 3.封装的实现步骤 需要注意:对封装的属性不一定要通过get/set方法,其他方法也可以对封装的属性进行操作.当然最好使用get/set方法,比较标准. A.访问修饰符 从表格可以看出从上到下封装性越来越差. B.this关键字 1.this关键字代表当前

[转]Java中继承、多态、重载和重写介绍

什么是多态?它的实现机制是什么呢?重载和重写的区别在那里?这就是这一次我们要回顾的四个十分重要的概念:继承.多态.重载和重写. 继承(inheritance) 简单的说,继承就是在一个现有类型的基础上,通过增加新的方法或者重定义已有方法(下面会讲到,这种方式叫重写)的方式,产生一个新的类型.继承是面向对象的三个基本特征--封装.继承.多态的其中之一,我们在使用JAVA时编写的每一个类都是在继承,因为在JAVA语言中,java.lang.Object类是所有类最根本的基类(或者叫父类.超类),如果

网络电视精灵~分析~~~~~~简单工厂模式,继承和多态,解析XML文档

小总结: 所用技术: 01.C/S架构,数据存储在XML文件中 02.简单工厂模式 03.继承和多态 04.解析XML文档技术 05.深入剖析内存中数据的走向 06.TreeView控件的使用 核心:通过该项目,我们对业务流程有一个整体把控.对继承和多态有深入的了解 下面是类图: 主界面图: 核心思路: 1   1.首先在频道管理类ChannelManager中写一个加载所有频道方法LoadAllChannel; 2   3        该方法作用读取FullChannels.xml文件,并且

对封装、继承、多态的理解。

1.封装     封装:就是隐藏对象的属性和实现细节,仅对外提供公共访问方式. 封装的具体步骤:修改属性的可见性来限制对属性的访问;为每个属性创建一对赋值(setter)方法和取值(getter)方法,用于对这些属性的存取;在赋值方法中,加入对属性的存取控制语句. 封装的好处主要有:隐藏类的实现细节;让使用者只能通过程序员规定的方法来访问数据;可以方便的加入存取控制语句,限制不合理操作. 封装时的权限控制符区别如下: 1 /* 2 * 封装演示 3 */ 4 public class Dog {

JavaScript基础--面向对象三大特性(八):继承封装多态

一.构造函数基本用法:function 类名(参数列表){属性=参数值} 1 function Person(name,age){ 2 this.name = name; 3 this.age = age; 4 } 5 6 //创建Person对象的时候,可以直接给名字和年龄 7 var p1 = new Person('abc',80); 8 window.alert(p1.name); 9 var p2 = new Person('hello',9); 10 window.alert(p2.