面向对象中的顶级装备《多天吧》

为了便于说明多态,先从一个简单的例子说起

#include <iostream>

using namespace std;

class Parent//定义一个父类Parent类
{
public:
    //构造函数
    Parent(int a = 1)
    {
        this->a = a;
    }

    //打印Parent类的数据成员
    void print()
    {
        cout<<"a = "<<a<<endl;
    }

private:
    int a;//数据成员

};

//Parent类派生出Child类
class Child : public Parent
{
public:

    //构造函数
    Child(int b = 2)
    {
        this->b = b;
    }

      //打印Child类的数据成员
    void print()
    {
        cout<<"b = "<<b<<endl;
    }

private:
    int b;//数据成员
};

//函数参数(指针作为函数参数)
void howToPrintf(Parent *base)
{
    base->print();
}

//函数参数(引用作为函数参数)
void howToPrintf(Parent &base)
{
    base.print();//同一句话实现多种功能,有多种形态
}

void main()
{
    Parent p1;//定义Parent类的对象p1
    p1.print();//打印p1的数据成员

    Child c1;//定义Child类的对象c1
    c1.print();//打印c1的数据成员

    //使用指针访问父类对象和子类对象
    cout<<"\n使用指针访问对象:"<<endl;
   Parent *base = NULL;
    base = &p1;
    base->print();
    base = &c1;
    base->print();//没有打印子类的函数

    //使用引用访问父类对象和子类对象
    cout<<"\n使用引用访问对象:"<<endl;
    //p2是p1的引用,p2是p1的别名,p2是p1本身
    Parent &p2 = p1;
    p2.print();

    //c2是c1的引用,c2是c1的别名,c2是c1本身
    p2 = p1;
    p2.print();

    //使用函数访问父类对象和子类对象
    cout<<"\n使用函数访问对象(父类指针作为函数参数):"<<endl;
    //函数参数(指针作为函数参数)
    howToPrintf(&p1);
    howToPrintf(&c1);

     //使用函数访问父类对象和子类对象
    cout<<"\n使用函数访问对象(父类引用作为函数参数):"<<endl;
    //函数参数(引用作为函数的参数)
    howToPrintf(p1);
    howToPrintf(c1);

    system("pause");
}

执行结果:

程序说明:

程序中本来计划实现扥功能是调用父类的print()函数,打印父类的数据成员,调用子类的print()函数,打印子类的数据成员,然后程序中只有当直接调用父类成员函数时才打印出来父类的数据成员和子类的数据成员,间接调用中都没有实现,为了解决这个问题,需要在父类和子类都相同的成员函数前都加上关键字 virtual

加上关键字virtual后就可以实现上面的功能

修改后的代码:

#include <iostream>

using namespace std;

class Parent//定义一个父类Parent类
{
public:
    //构造函数
    Parent(int a = 1)
    {
        this->a = a;
    }

    //打印Parent类的数据成员
    virtual void print()
    {
        cout<<"a = "<<a<<endl;
    }

private:
    int a;//数据成员

};

//Parent类派生出Child类
class Child : public Parent
{
public:

    //构造函数
    Child(int b = 2)
    {
        this->b = b;
    }

      //打印Child类的数据成员
    virtual void print()
    {
        cout<<"b = "<<b<<endl;
    }

private:
    int b;//数据成员
};

//函数参数(指针作为函数参数)
void howToPrintf(Parent *base)
{
    base->print();
}

//函数参数(引用作为函数参数)
void howToPrintf(Parent &base)
{
    base.print();//同一句话实现多种功能,有多种形态
}

void main()
{
    Parent p1;//定义Parent类的对象p1
    p1.print();//打印p1的数据成员

    Child c1;//定义Child类的对象c1
    c1.print();//打印c1的数据成员

    //使用指针访问父类对象和子类对象
    cout<<"\n使用指针访问对象:"<<endl;
   Parent *base = NULL;
    base = &p1;
    base->print();
    base = &c1;
    base->print();//没有打印子类的函数

    //使用引用访问父类对象和子类对象
    cout<<"\n使用引用访问对象:"<<endl;
    //p2是p1的引用,p2是p1的别名,p2是p1本身
    Parent &p2 = p1;
    p2.print();

    //c2是c1的引用,c2是c1的别名,c2是c1本身
    p2 = p1;
    p2.print();

    //使用函数访问父类对象和子类对象
    cout<<"\n使用函数访问对象(父类指针作为函数参数):"<<endl;
    //函数参数(指针作为函数参数)
    howToPrintf(&p1);
    howToPrintf(&c1);

     //使用函数访问父类对象和子类对象
    cout<<"\n使用函数访问对象(父类引用作为函数参数):"<<endl;
    //函数参数(引用作为函数的参数)
    howToPrintf(p1);
    howToPrintf(c1);

    system("pause");
}

执行结果:

说明:

1、上面的代码中实现了间接访问的方式实现父类和子类的数据成员的输出,而且都是用同一个函数实现的,在面向对象中将这种同一个语句实现多种功能的方式叫做多态

2、上面的代码中出现了两个print()函数,容易将print()函数看成是函数重载,其实print()函数不是函数重载,函数重载必须是在同一个作用域中,或者同一个类中,上面的代码中的print()函数分别在两个不同的类中,所以不是函数重载,而且函数重载是指函数名相同,函数的参数不同的同一类函数,代码中函数都没有参数也不满足重载函数最基本的条件,而代码中的ShowToPrintf()函数满足函数重载的条件,所以ShowToPrintf()函数属于函数重载

多态成立的三个条件

1要有继承

2要有函数重写

3父类指针指向子类对象

时间: 2024-10-14 00:50:15

面向对象中的顶级装备《多天吧》的相关文章

PHP 面向对象中常见关键字使用(final、static、const和instanceof)

PHP 面向对象中常见关键字的使用: 00x1.Final :final关键字可以加在类或者类中方法之前,但是不能使用final标识成员属性. 作用: 使用final标识的类,不能被继承. 在类中使用final标识的成员方法,在子类中不能覆盖. 总结:final表示为最终的意思,所以使用final关键字的类或者类中的成员方法是不能被更改的. 00x2.Static :static关键字将类中的成员属性或者成员方法标识为静态的,static标识的成员属性属于整个类,static成员总是唯一存在的,

对php面向对象中魔术方法的认识

<?php//header(charset="utf8");    //echo 'hey 这里是描述我对php 面向对象中各种魔术方法的认识.';/* *魔术方法是在一些特定情况下会自动调用的一些php系统自定义函数 *这些函数都很有个性,他们统一以__两个 _ (下划线)开头. * 下面对于php 中这些常用的魔术方法一些个人认识. **/class demo {    public $name;    public $age; //当实例化这个类,首先会自动调用的方法 __

PHP中的面向对象 中的类(class)

2.11 上午讲的是面向对象中的类(class),一个非常抽象的概念, 类里面成员的定义有 public$abc; private$abc(私有变量): protect $abc(受保护的变量): 下面是用实例来解释一下class <?php class test_123 { public $a; public $b; function squar() { return $this->a*$this->b; //这里求的是矩形的面积,由于class中定义的都是抽象的,所以这里需要把a.b

面向对象中一个疏漏的知识

关于访问修饰符一个重要的问题. private是限制该对象无法在外部对象中访问,但是如果在自己的类中创建自己的对象或者使用自己的对象,那么还是可以使用被private修饰的成员 class A{ public class StringValue { public static void main(String[] args){ A a = new A(); a.i = 1; //这里无法访问,报错! } } class A{ private int i; public boolean equal

面向对象中的原型和原型链

今天我们要说的是面向对象中的原型链,在说原型链之前,我们先一步一步来了解一下面向对象中的一些基本概念. 一.类 类是指具有相同特征(属性)和行为(方法)的事物的集合. 二.对象 对象的目的实际上是将具有相同属性和行为的代码整合在一起,方便我们的管理. 起初,我们是这样来创建一个对象的, js代码: var person1 = { name:"张三", age:18, height:165, walk:function(){ console.log("i can walk!&q

文成小盆友python-num8 面向对象中的成员,成员修饰符,特殊成员,异常处理,设计模式之单例模式

本节主要内容: 1.面向对象中的成员 2.成员修饰符 3.特殊成员 4.异常处理 5.设计模式之单例模式 一.面向对象中的成员(类的成员) 类的成员总共可以分为3大类,每类中有不同的分支. 1.总述,基本分类 如下图所示: 类成员包括字段,方法,和属性 2.字段 如上图字段分为普通字段和静态字段,两者的使用有区别,但是最大的区别在于两者在内存中的保存位置有区别. 普通字段属于对象而静态字段属于类,在使用过程中谁的字段就由谁来调用. 静态字段和普通字段的定义如下: 在调用时分各自调用 #####类

深入分析面向对象中的封装作用

之前我(梦在旅途)发表过一篇名为<深入分析面向对象中的对象概念>的文章,里面主要讲解了类与对象的关系以及对象的概念.状态.行为.角色几个知识点,让大家对对象有了一些深入的了解,而本文则再来谈谈面向对象的三大特性之一:封装,封装是实现面向对象的基础,深入的理解封装的特性,有利于我们能更好的领悟面向对象的思想以及实现面向对象编程.以下均为本人凭借多年开发经验总结的个人观点,大家若发现有误或不足的地方,欢迎指正和交流,谢谢! 一.什么是封装? 顾名思义,封:封闭,装:装起来,将具体的实现细节装到一个

面向对象中的接口和多态

接口的作用是用来制定规范,以便让后面的程序根据这个规范来实现. 接口的声明方式:interface 接口名{},接口只能声明抽象方法,至少要有一个,但是声明的抽象方法前不需要用abstract修饰. 声明一个类实现接口,class demo implements interface_name {},当一个类实现接口的时候,这个类必须实现接口里定义的所有抽象方法.一个类可以既同时继承一个类又实现多个接口,class demo2 extends demo implements interface1,

第05章(面向对象——中)

1 /***************** 2 ***第五章面向对象(中) 3 *******知识点: 4 **************1.多态 5 ******************1.1 概念 6 ******************1.2 实现方式 7 **************2.抽象类 8 ******************2.1 关键字 9 ******************2.2 概念定义 10 ******************2.3 使用 11 ************