面向对象编程的三大特性


封装、继承、多态

一、封装
将数据和基于数据的操作封装在一起,使其构成一个不可分割的独立实体,每个对象都能包含它所进行操作所需要的所有信息,而不必依赖于其他对象。数据是被保护在抽象数据类型的内部,尽可能地隐藏内部的细节,只保留一些对外的接口使其与外部发生联系。用户可以只关注于使用,而不关心具体的实现,用户也无需关心对象内部的细节,可以通过该对象对外提供的接口来访问该对象的内部数据。

优点:
(1)低耦合性:可以独立地进行开发、测试、优化
(2)类的内部实现可以自由的修改:可以独立的进行调试
(3)有效地调节性能:可以通过剖析来确定哪些模块影响了系统的性能
(4)可重用
(5)降低了构建大型系统的风险:即使整个系统不可用,但是这些独立的模块却有可能是可用的
(6)不必关心具体实现
(7)具有安全性
(8)具有清晰的对外接口
举一个person类来说明,类封装了名字、性别、年龄等属性,外界能通过一个get方法获取一个实例person对象的name属性、性别属性,但是无法获得年龄属性,但是可以通过其它方法使用age属性。封装之后,各种属性的数据类型这些细节是用户注意不到的。
代码如下:
    
    

#include <iostream>
    using namespace std;
     class Person {
    
        private:
        string name;
         int gender;
         int age;
        public:
         Person(string name,int gender,int age):name(name),gender(gender),age(age){}
       
            string getName() {
            return name;
        }
    
        string getGender() {
            return gender == 0 ? "man" : "woman";
        }
    
        void work() {
            if (18 <= age && age <= 50) {
                cout<<name << " is working very hard!";
            } else {
                cout<<name << " can't work any more!";
            }
        }
    };
    int main() {
        Person* a=new Person("123",1,23);
        a->work();
        cout<<endl;
        cout<<a->getName()<<endl;
        cout<<a->getGender();
        return 0;
    }


输出:
123 is working very hard!
123
woman

二、继承

继承是实现了一种IS-A 关系,例如Cat和 Animal 就是一种 IS-A 关系,因为我们可以说cat是动物,但是不能说动物是animal,因此 Cat 可以继承自 Animal,从而获得 Animal 非 private 的属性和方法,构造函数不能被继承,只能被调用。继承者也可以理解为对被继承者的特殊化,因为它除了具备被继承者的特性外,还具备自己独有的个性,例如猫会上树,但不是所有的动物都能上树。很明显继承就是一种类与类之间强耦合的关系,所以继承存在缺点,父类变化,子类就不得不变,而且继承会破坏包装,父类的实现细节暴露给了子类。

子类对象能够替换掉父类对象,Cat 可以当做 Animal 来使用,也就是说可以使用 Animal 引用 Cat 对象。父类引用指向子类对象称为 向上转型 。例如:Animal animal = new Cat();

三、多态

多态分为静态多态和动态多态,多态是说对于同一条命令时,对于不同的对象,会做出不同的动作或者相同对象对于不同消息产生的动作。
静态多态:
是编译时多态,主要指方法的重载,早绑定,在程序编译之前就知道使用哪个函数了,即在同一个类中有相同的函数名,也就是函数重载,
例如:
 A a;
 a.f_1(1);
 a.f_1(1,2);
动态多态:
指程序中定义的对象引用所指向的具体类型在运行期间才确定,它的特点是晚绑定,运行时多态,覆盖,重写。
例如:

    

#include<iostream>
    using namespace std;
    class base
    {
        public:
         virtual ~base(){}
    virtual void fun(){cout<<"base::fun"<<endl;}
    
    };
    class drive:public base
    {
        public:
    virtual void fun(){cout<<"drive::fun"<<endl;}
    };
    int main()
    {
        base * p=new drive;
       p->fun();
    system("pause");
    return 0;
    }



输出是:
drive::fun

由上可以看出,运行时多态有三个条件:
继承
覆盖(重写)
向上转型
在上述的例子中,基类有一个子类,覆盖了父类的fun方法,并在main中用父类指针来指向子类对象,但是在调用fun函数时,会执行实际指向对象所在类的fun方法,而不是父类的方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值