面向对象三要素:封装继承多态的阐述及示例

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

一 封装

  封装就是将数据与操作数据的源代码进行有机的结合,形成类,其中数据和函数都是类的成员。隐藏了类的实现,类的使用者只需知道公共的接口,就可以使用该类;封装帮助防止意外的改变和误用;对程序调试有很大的帮助,因为改变类的成员变量只用通过公共接口。   谈到封装,就必然有类的存在。类类似结构体,但它更多功能和更灵活:

class Date   //类的声明没有分配内存,只是说明了类的结构
{
public:     //类的成员可以使用标识符来控制它们的可访问性
     int year;   //类的成员变量
     int month;
     void SetDate(int year,int month)  //类的成员函数
     {
         this->year = year;
         this->month = month;
     }  
};   //类的声明以分号结尾

  为了使用类,可以声明一个该类型的变量:

Date today;   //类的实例化
today.year = 2016;  //类的一个实例,访问成员变量
today.month = 5;
today.SetDate(2016,5); //访问成员函数

  接下来举个封装实现的例子:

class Change
{
private:
    int m_value;
public:
    int GetValue(){return m_value;}
    void SetValue(int value){this->m_value=value;}
    static int _num;  //声明静态成员
};
int Change::_num = 0;  //静态数据成员的真正定义
int main()
{
    Change change;
    change.SetValue(100);
    cout << change.GetValue() << endl;
    system("pause");
    change._num++;
    cout << change._num <<endl;
    return 0;
}

  备注:静态成员变量是属于类的本身,是所有对象的共享变量;它的值是保持修改的最新值;使用格式:类名::静态成员;初始化必须在类的代码文件中进行;声明为static的静态成员可以在类的范围内共享。

二 继承

  继承是指可以使用现有类的所有功能,可以使一个对象直接使用另一个对象的属性和方法。通过继承创建的新类称为“子类”或者“派生类”,被继承的类称为“基类”或者“父类”。

class base{  
public:  
    base(){  
        a = 0;  
        b = 1;  
        c = 2;  
    }  
    int a;  
protected:  
    int b;  
private:  
    int c;  
}; 
// 接下来是三种继承方式 
class derived1 : public base{//public继承  
public:  
    void fun(){//derived class可以访问public和protected member  
        cout<<base::a<<base::b<<endl;  
    //  cout<<base::c;//不能访问  
    }  
};  
class derived2 : protected base{//protected继承  
public:  
    void fun(){//derived class可以访问public和protected member  
        cout<<base::a<<base::b<<endl;  
     // cout<<base::c;//不能访问  
    }  
};  
class derived3 : private base{//private继承  
public:  
    void fun(){//derived class可以访问public和protected member  
        cout<<base::a<<base::b<<endl;  
     // cout<<base::c;//不能访问  
    }  
};  
class derived4 : public derived3{//base的member不能被private继承的派生类的子类访问  
public:  
    void fun(){  
    //  cout<<a;  
    }  
};  
class derived5 : base{//默认private继承  
    void fun(){//derived class可以访问public和protected member  
        cout<<base::a<<base::b;  
        // cout<<base::c;//不能访问  
    }     
};  
int main(void)  
{  
    base b1;  
    derived1 d1;  
    derived2 d2;  
    derived3 d3;  
    d1.fun();  
    d2.fun();  
    d3.fun();  
    cout<<b1.a;//base class Object只能访问public member  
    cout<<d1.a;//public继承时 derived class Object只能访问base class的public member  
    //cout<<d1.b<<d1.c;//不能访问  
    //cout<<d2.a<<d2.b;//protected继承时 derived class Object不能问访base class的member  
    //cout<<d3.a;//private继承时 derived class Object不能问访base class的member  
    return 0;  
}  

三 多态

  多态性可以简单地概括为“一个接口,多种方法”,程序在运行时才决定调用的函数,它是面向对象编程领域的核心概念。   C++多态性是通过虚函数来实现的,虚函数允许子类重新定义成员函数,而子类重新定义父类的做法称为覆盖(override),或者称为重写。重载则是允许有多个同名的函数,而这些函数的参数列表不同,允许参数个数不同,参数类型不同,或者两者都不同。编译器会根据这些函数的不同列表,将同名的函数的名称做修饰,从而生成一些不同名称的预处理函数,来实现同名函数调用时的重载问题。   多态有动态多态,静态多态,函数多态和宏多态。常说的多态是指动态多态,它是基于继承机制和虚函数来实现的。   宏多态的例子:

#define ADD{A,B} (A) + (B);
int main()
{
    int i1(1),i2(2);
    std::string s1("I,"),s2("am");
    int i = ADD{i1,i2};   //两个整数相加
    std::string s = ADD{s1,s2}; //两个字符串相加,连接
}
class A   //父类
{
public:
 void foo()
 {
  printf("1\n");
 }
 virtual void fun()
 {
  printf("2\n");
 }
};
class B : public A   //子类
{
public:
 void foo()
 {
  printf("3\n");
 }
 void fun()
 {
  printf("4\n");
 }
};
int main(void)
{
 A a;
 A *p = &a;
 p->foo();  //本身是基类指针,指向的又是基类对象,
 p->fun();  //调用的都是基类本身的函数,因此输出结果就是1、2。
 p = &b;    //基类指针指向子类对象,这就是多态
 p->foo();  //指向的固定偏移量的函数,结果还为1
 p->fun();  //指向虚函数,通过虚函数找到相应函数地址
 return 0;
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏大前端_Web

C#中值类型和引用类型及类型的转换

版权声明:本文为吴孔云博客原创文章,转载请注明出处并带上链接,谢谢。 https://blog.csdn.net/wkyseo/articl...

2546
来自专栏Linux驱动

快速排序(详解)

描述: 通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序...

1909
来自专栏Python数据科学

Python 内建函数大全

Python 解释器内置了许多函数和类型,列表如下(按字母排序)(省略了几个我没用过或者不常用的)。

1583
来自专栏Esofar 开发日记

SQL Server常见数据类型介绍

923
来自专栏代码世界

Python基础数据类型之集合以及其他和深浅copy

一、基础数据类型汇总补充 list  在循环一个列表时,最好不要删除列表中的元素,这样会使索引发生改变,从而报错(可以从后向前循环删除,这样不会改变未删元素的索...

2999
来自专栏CVer

排序算法 | 冒泡排序(含C++/Python代码实现)

排序算法,就是如何使得记录按照要求排列的方法。排序算法在很多领域得到相当地重视,尤其是在大量数据的处理方面。排序算法有很多,本文将介绍最经典的排序算法:冒泡排序...

942
来自专栏Pythonista

python内建函数

abs()函数返回数字(可为普通型、长整型或浮点型)的绝对值。如果给出复数,返回值就是该复数的模。例如:

1151
来自专栏炉边夜话

java 异常处理学习笔记

<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

772
来自专栏决胜机器学习

《Redis设计与实现》读书笔记(六) ——Redis中的压缩列表

《Redis设计与实现》读书笔记(六) ——Redis中的压缩列表 (原创内容,转载请注明来源,谢谢) 一、概述 压缩列表(ziplist)是列表键(list)...

3787
来自专栏python成长之路

lambda函数常见用法

1725

扫码关注云+社区