封装、继承、多态

一,封装
定义:
通常会将类中属性和一些方法进行隐藏。通常是把属性设为私有,这时访问就需要通过公共的接口。可以控制属性读和写的权限,提高程序的安全性。

练习:
#include <iostream>
using namespace std;
class Person{
private:  //私有权限 只能类中访问
    string name; //姓名  可读,可写
    string address; //地址  只读
    string password="123456"; //密码 只写
public:
    string getName(){
        return name;
    }
    void setName(string str){
        name=str;
    }
    void getAddress(){
        cout<<"定位地址为山东"<<endl;
    }
    void setPassword(string str){
       password=str;
    }
 
};
int main()
{
    Person p;
    //p.name="小明"; //name是私有权限  类外访问不到
    p.setName("小明");
    p.setPassword("123789");
 
    cout<<"姓名"<<p.getName()<<endl; //姓名小明
    p.getAddress();   //定位地址为山东
 
}

二,继承
1.定义:
在已存在类的基础上,创建新的类。会拥有原有类的一些特性。通常会在原有类基础上做修改和增加操作。

已经存在的类成为父类或基类

新创建的类称为子类或派生类

练习:
#include <iostream>
using namespace std;
class Father{
public:
    string first_name="李";
    void work(){
        cout<<"我是名厨师"<<endl;
    }
};
class Son:public Father{ //公共继承
 
};
int main()
{
    Son s;
    cout<<s.first_name<<endl;
    s.work();
}
函数隐藏:如果子类中给出与父类同名的函数,父类中所有同名函数都被隐藏。如果需要访问需要父类的作用域限定符的方式进行访问

举例:
#include <iostream>
using namespace std;
class Father{
public:
    string first_name="李";
    void work(){
        cout<<"我是名厨师"<<endl;
    }
};
class Son:public Father{ //公共继承
public: //权限不写默认是私有的
    void work(){
        cout<<"嵌入式工程师"<<endl;
    }
    void study(){
        cout<<"喜欢学习"<<endl;
    }
};
int main()
{
    Son s;
    cout<<s.first_name<<endl;
    s.work();
    s.Father::work();//可以访问被隐藏的父类函数
    s.study();
}
 
 
2.继承注意事项
父类的构造函数不会继承下来
子类一定要直接或者间接的调用父类的构造函数。来完成从父类继承过来数据的初始化。如果子类不写明如何调用父类的构造函数,这时会调用父类无参的构造函数,如果父类中没有无参的构造函数,这时就会报错
举例:
#include <iostream>
using namespace std;
class Father{
private:
    string name;
public:
    Father(string name){
        this->name=name;
    }
    void work(){
        cout<<name<<"是名厨师"<<endl;
    }
};
class Son:public Father{ //公共继承
 
};
int main()
{
    Son s;
    s.work();
 
}
3.权限
注意:权限不写默认是私有

不同权限访问情况
不同权限的成员,在不同位置的可访问情况

public            本类中可以可以访问          在子类中可以访问          在全局中可以访问

protected      本类中可以可以访问          在子类中可以访问          在全局中不可以访问

private          本类中可以可以访问          在子类中不可访问   在全局中不可以访问

不同权限的继承 
任何权限的继承,私有权限成员继承之后,都不能直接访问
排除私有成员的情况下,公有继承全不变,保护继承变保护,私有继承变私有
4.多继承
多继承使用
一个类有多个基类,这时就是多继承  。实际开发中要避免使用多继承,多继承造成的问题复杂度高于便利性

#include <iostream>
using namespace std;
class Bed{
public:
    void lay(){
        cout<<"可以躺着"<<endl;
    }
};
class Sofa{
public:
    void sit(){
        cout<<"可以坐着"<<endl;
    }
 
};
class SofaBed:public Bed,public Sofa{
};
int main()
{
    SofaBed sf;
    sf.lay();
    sf.sit();
}
多继承二义性问题
不同的基类拥有同名成员,此时派生类的调用会出现二义性问题,可以通过类名加作用域限定符的方式进行区分,避免二义性

#include <iostream>
using namespace std;
class Bed{
public:
    void lay(){
        cout<<"可以躺着"<<endl;
    }
    void position(){
        cout<<"放在卧室"<<endl;
    }
 
};
class Sofa{
public:
    void sit(){
        cout<<"可以坐着"<<endl;
    }
    void position(){
        cout<<"放在客厅"<<endl;
    }
 
};
class SofaBed:public Bed,public Sofa{
 
};
int main()
{
    SofaBed sf;
    sf.lay();
    sf.sit();
    //sf.position(); //从Bed和Sofa都继承了position()函数,调用时会不明确
    sf.Bed::position();
    sf.Sofa::position();
 
}
 
三,多态 
多态概念和条件(掌握)
字面意思多种状态,可以简单概括就是一个接口,多种状态。动态的决定程序调用的代码

静态多态:编译期就确定下来应该调用哪个方法。比如函数重载,运算符重载

动态多态:运行的时候,才确定具体调用哪个函数。这时需要用到虚函数

运行时多态的三个条件:

公有继承
基类的指针或者引用指向派生类对象
派生类覆盖基类的虚函数
运行时多态的三个条件:

公有继承
基类的指针或者引用指向派生类对象
派生类覆盖基类的虚函数
#include <iostream>
using namespace std;
class Animal{
public:
    void eat(){
        cout<<"吃东西"<<endl;
    }
};
class Cat:public Animal{
public:
    void eat(){
        cout<<"吃鱼"<<endl;
    }
};
class Dog:public Animal{
public:
    void eat(){
        cout<<"吃狗粮"<<endl;
    }
};
//void test1(Cat& c){
//    c.eat();
//}
//void test2(Dog& d){
//    d.eat();
//}
 
//所有Aniamal类的派生类都可以传入,实现了公共接口
void test(Animal& a){
    a.eat();
}
void test(Animal* a){
    a->eat();
}
int main()
{
    Cat cat1;
    test(cat1); //吃东西
    Dog dog1;
    test(dog1); //吃东西
 
    Dog dog2;
    test(&dog2);//吃东西
}
多态的实现(掌握)
运行时多态的实现需要用到虚函数,虚函数就是virtual关键字修饰的函数

函数覆盖和虚函数的特点:

1.当函数覆盖成功时,虚函数具有传递性

2.C++11中可以在派生类的新覆盖的函数后增加override关键字进行覆盖是否成功的验证

3.成员函数与析构函数可以定义为虚函数,静态成员函数与构造函数不可以定义为虚函数,因为构造函数不能被派生类继承,也就没办法覆盖重写。静态成员函数与对象无关

如果成员函数的声明与定义分离,virtual关键字只需加在声明处
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值