28.接口

28.面向对象关联知识点-接口


28.1 知识点

什么是接口

  • 接口其实是C#和Java中的一个关键词interface

  • 它是一种行为的抽象规范

  • 我们可以继承接口来表示行为的继承

  • 但是在C++中并没有专门的接口关键字

  • 因此,为了表示行为的继承,我们经常需要在C++中模拟接口

  • 什么是行为的抽象

    • 飞机、鸟、超级赛亚人、超人
    • 他们其实不属于同一种类型,但是都会飞
    • 如果我们用面向对象的思想,其实不太好将他们归纳出一个基类
    • 因此我们往往会把他们的行为抽象出来,声明一个表示行为的接口基类

C++中如何模拟接口

  • C++中实现接口的本质:只有纯虚函数的抽象类
  • 接口类命名规范为:I类名(I表示该类是一个接口Interface)
  • 接口类中建议只包含纯虚函数和虚析构函数,不建议包含成员变量和普通函数
  • 接口类一般只需要 .h,因为不需要实现
#pragma once
// 飞行接口类
class IFly
{
public:
    virtual void Fly() = 0;
};

接口类的使用

#pragma once
class Animal
{
};
#pragma once
#include "IFly.h"
class SuperMan : public IFly
{
public:
    void Fly() override
    {

    }
};
#pragma once
#include "Animal.h"
#include "IFly.h"
class Brid :
    public Animal, public IFly
{
public:
    void Fly() override
    {

    }
};
  • 接口的作用:可以用接口作为父类装进数组中
IFly* f[2] = { new SuperMan(), new Brid() };

接口类可以继承接口类

  • 接口类继承接口类时,不需要去实现,待对象类继承接口后,类自己去实现所有内容即可
#pragma once
// 行走接口类
class IWalk
{
public:
    virtual void Walk() = 0;
};
#pragma once
#include "IFly.h"
#include "IWalk.h"
// 移动接口类
class IMove : public IFly, public IWalk
{
};
#pragma once
#include "Animal.h"
#include "IMove.h"
class Person :
    public Animal, public IMove
{
public:
    void Fly() override
    {

    }

    void Walk() override
    {

    }
};

总结

  • 继承类:是对象间的继承,包括特征和行为
  • 继承接口类:是行为间的继承,继承接口类的行为规范,按照规范去进行实现即可
  • 由于接口类也是类,它遵循里氏替换原则,因此可以用接口类容器去装载对象
  • 可以实现装载各种毫无关系但是却有相同行为的对象了

28.2 知识点代码

Animal.h

#pragma once
class Animal
{

};

IFly.h

#pragma once
//飞行接口类
class IFly
{
public:
    virtual void Fly() = 0;
};

IMove.h

#pragma once
#include "IFly.h"
#include "IWalk.h"
//移动接口类
class IMove : public IFly, public IWalk
{
};

IWalk.h

#pragma once
//行走接口类
class IWalk
{
public:
    virtual void Walk() = 0;
};

Brid.h

#pragma once
#include "Animal.h"
#include "IFly.h"
class Brid :
    public Animal, public IFly
{
public:
    void Fly() override
    {

    }
};

Person.h

#pragma once
#include "Animal.h"
#include "IMove.h"
class Person :
    public Animal, public IMove
{
public:
    void Fly() override
    {

    }

    void Walk() override
    {

    }
};

SuperMan.h

#pragma once
#include "IFly.h"
class SuperMan : public IFly
{
public:
    void Fly() override
    {

    }
};

Lesson28_面向对象关联知识点_接口.cpp

#include <iostream>
#include "Brid.h"
#include "SuperMan.h"
int main()
{
    #pragma region 知识点一 什么是接口
    //接口其实是C#和Java中的一个关键词interface
    //它是一种行为的抽象规范
    //我们可以继承接口来表示行为的继承
    //但是在C++中并没有专门的接口关键字
    //因此,为了表示行为的继承,我们经常需要在C++中模拟接口

    //什么是行为的抽象
    //比如:
    //飞机、鸟、超级赛亚人、超人
    //他们其实不属于同一种类型,但是都会飞
    //如果我们用面向对象的思想,其实不太好将他们归纳出一个基类
    //因此我们往往会把他们的行为抽象出来,声明一个表示行为的接口基类
    #pragma endregion

    #pragma region 知识点二 C++中如何模拟接口
    //C++中实现接口的本质:
    // 只有纯虚函数的抽象类

    //注意:
    //1.接口类命名规范为: I类名
    //	I表示该类是一个接口(Interface)
    //	注意:这是一个比较通用的命名规范
    //2.接口类中建议只包含纯虚函数和虚析构函数,不建议包含成员变量和普通函数
    //3.接口类一般只需要.h,因为不需要实现
    #pragma endregion

    #pragma region 知识点三 接口类的使用


    //接口的作用:可以用接口作为父类装进数组中
    IFly* f[2] = { new SuperMan(), new Brid() };
    
    #pragma endregion

    #pragma region 知识点四 接口类可以继承接口类
    //接口类继承接口类时,不需要去实现
    //待对象类继承接口后,类自己去实现所有内容即可
    #pragma endregion

    //总结
    //继承类:是对象间的继承,包括特征和行为
    //继承接口类:是行为间的继承,继承接口类的行为规范,按照规范去进行实现即可
    //由于接口类也是类,他是遵循我们里式替换原则的,因此可以用接口类容器去装载对象
    //那么就可以实现 装载各种毫无关系但是却有相同行为的对象了

}

28.3 练习题

人、汽车、房子都需要登记,人需要到派出所登记,汽车需要去车管所登记,房子需要去房管局登记,使用接口实现登记方法

定义登记接口类:

#pragma once
class IRegister
{
public:
    virtual void Register() = 0;
};

实现人类并继承登记接口:

#pragma once
#include "IRegister.h"

class Person : public IRegister
{
public:
    void Register() override;
};
#include "Person.h"
#include <iostream>
using namespace std;

void Person::Register()
{
    cout << "派出所登记" << endl;
}

实现汽车类并继承登记接口:

#pragma once
#include "IRegister.h"

class Car : public IRegister
{
public:
    void Register() override;
};
#include "Car.h"
#include <iostream>
using namespace std;

void Car::Register()
{
    cout << "车管所登记" << endl;
}

实现房子类并继承登记接口:

#pragma once
#include "IRegister.h"

class Home : public IRegister
{
public:
    void Register() override;
};
#include "Home.h"
#include <iostream>
using namespace std;

void Home::Register()
{
    cout << "房管局登记" << endl;
}

示例调用代码:

IRegister* person = new Person();
person->Register();
delete person;
person = nullptr;

IRegister* car = new Car();
car->Register();
delete car;
car = nullptr;

IRegister* home = new Home();
home->Register();
delete home;
home = nullptr;

输出结果:

派出所登记
车管所登记
房管局登记

麻雀、鸵鸟、企鹅、鹦鹉、直升机、天鹅行为建模

直升机和部分鸟能飞,鸵鸟和企鹅不能飞,企鹅和天鹅能游泳,除直升机外其它都能走。以下是使用接口和继承进行面向对象建模的实现:

鸟类基类定义:

#pragma once
class Brid
{
public:
    virtual void Walk() = 0;
};

飞行接口定义:

#pragma once
class IFly
{
public:
    virtual void Fly() = 0;
};

游泳接口定义:

#pragma once
class ISwimming
{
public:
    virtual void Swimming() = 0;
};

麻雀类:能走、能飞

#pragma once
#include "Brid.h"
#include "IFly.h"

class Sparrow : public Brid, public IFly
{
public:
    void Walk() override
    {
    }

    void Fly() override
    {
    }
};

鸵鸟类:只能走

#pragma once
#include "Brid.h"

class Ostrich : public Brid
{
public:
    void Walk() override
    {
    }
};

企鹅类:能走、能游泳

#pragma once
#include "Brid.h"
#include "ISwimming.h"

class Penguin : public Brid, public ISwimming
{
public:
    void Walk() override
    {
    }

    void Swimming() override
    {
    }
};

鹦鹉类:能走、能飞

#pragma once
#include "Brid.h"
#include "IFly.h"

class Parrot : public Brid, public IFly
{
public:
    void Walk() override
    {
    }

    void Fly() override
    {
    }
};

直升机类:只能飞

#pragma once
#include "IFly.h"

class Helicopter : public IFly
{
public:
    void Fly() override
    {
    }
};

天鹅类:能走、能飞、能游泳

#pragma once
#include "Brid.h"
#include "IFly.h"
#include "ISwimming.h"

class Swan : public Brid, public IFly, public ISwimming
{
public:
    void Walk() override
    {
    }

    void Fly() override
    {
    }

    void Swimming() override
    {
    }
};

多态模拟移动硬盘、U盘、MP3连接电脑读取数据

移动硬盘与U盘属于存储设备,MP3属于播放设备,但它们都能通过USB接口传输数据。

定义USB接口:

#pragma once
class IUSB
{
public:
    virtual void ReadData() = 0;
};

存储设备类定义:

#pragma once
#include <iostream>
#include "IUSB.h"
using namespace std;

class StorageDevice : public IUSB
{
public:
    string name;

    StorageDevice(string name);

    void ReadData() override;
};
#include "StorageDevice.h"

StorageDevice::StorageDevice(string name)
{
    this->name = name;
}

void StorageDevice::ReadData()
{
    cout << name << "传输数据" << endl;
}

MP3类定义:

#pragma once
#include "IUSB.h"

class MP3 : public IUSB
{
public:
    // 可能会有MP3作为播放器相关的行为
    void ReadData() override;
};
#include "MP3.h"
#include <iostream>
using namespace std;

void MP3::ReadData()
{
    cout << "MP3传输数据" << endl;
}

电脑类定义:

#pragma once
#include "IUSB.h"

class Computer
{
public:
    IUSB* usb1;
};

使用示例:

Computer* computer = new Computer();

StorageDevice* hd = new StorageDevice("移动硬盘");
StorageDevice* ud = new StorageDevice("U盘");
MP3* mp3 = new MP3();

computer->usb1 = hd;
computer->usb1->ReadData();

computer->usb1 = ud;
computer->usb1->ReadData();

computer->usb1 = mp3;
computer->usb1->ReadData();

// 移动硬盘传输数据
// U盘传输数据
// MP3传输数据

// 没有插入任何设备(对象)
computer->usb1 = nullptr;

// 如果这些设备不想用了 直接移除
delete hd;
hd = nullptr;

delete ud;
ud = nullptr;

delete mp3;
mp3 = nullptr;

28.4 练习题代码

IRegister.h

#pragma once
//登记接口类
class IRegister
{
public:
    virtual void Register() = 0;
};

Person.h

#pragma once
#include "IRegister.h"
class Person : public IRegister
{
public:
    void Register() override;
};

Person.cpp

#include "Person.h"
#include <iostream>
using namespace std;
void Person::Register()
{
    cout << "派出所登记" << endl;
}

Car.h

#pragma once
#include "IRegister.h"
class Car :
    public IRegister
{
public:
    void Register() override;
};

Car.cpp

#include "Car.h"
#include <iostream>
using namespace std;
void Car::Register()
{
    cout << "车管所登记" << endl;
}

Home.h

#pragma once
#include "IRegister.h"
class Home :
    public IRegister
{
public:
    void Register() override;
};

Home.cpp

#include "Home.h"
#include <iostream>
using namespace std;
void Home::Register()
{
    cout << "房管局登记" << endl;
}

IFly.h

#pragma once
//飞行接口类
class IFly
{
public:
    virtual void Fly() = 0;
};

ISwimming.h

#pragma once
//游泳接口类
class ISwimming
{
public:
    virtual void Swimming() = 0;
};

Sparrow.h

#pragma once
#include "Brid.h"
#include "IFly.h"
class Sparrow :
    public Brid, public IFly
{
public:
    void Walk() override
    {

    }

    void Fly() override
    {

    }
};

Ostrich.h

#pragma once
#include "Brid.h"
class Ostrich :
    public Brid
{
public:
    void Walk() override
    {

    }
};

Penguin.h

#pragma once
#include "Brid.h"
#include "ISwimming.h"
class Penguin :
    public Brid, public ISwimming
{
public:
    void Walk() override
    {

    }

    void Swimming() override
    {

    }
};

Parrot.h

#pragma once
#include "Brid.h"
#include "IFly.h"
class Parrot :
    public Brid, public IFly
{
public:
    void Walk() override
    {

    }

    void Fly() override
    {

    }
};

Helicopter.h

#pragma once
#include "IFly.h"
class Helicopter :
    public IFly
{
public:
    void Fly() override
    {

    }
};

Swan.h

#pragma once
#include "Brid.h"
#include "IFly.h"
#include "ISwimming.h"
class Swan :
    public Brid, public IFly, public ISwimming
{
public:
    void Walk() override
    {

    }

    void Fly() override
    {

    }

    void Swimming() override
    {

    }
};

IUSB.h

#pragma once
class IUSB
{
public:
    virtual void ReadData() = 0;
};

StorageDevice.h

#pragma once
#include <iostream>
#include "IUSB.h"
using namespace std;
class StorageDevice : public IUSB
{
public:
    string name;
    StorageDevice(string name);
    void ReadData() override;
};

StorageDevice.cpp

#include "StorageDevice.h"

StorageDevice::StorageDevice(string name)
{
    this->name = name;
}

void StorageDevice::ReadData()
{
    cout << name << "传输数据" << endl;
}

MP3.h

#pragma once
#include "IUSB.h"
class MP3 : public IUSB
{
public:
    //可能会有MP3作为播放器相关的行为
    //可以自己去实现

    void ReadData() override;
};

MP3.cpp

#include "MP3.h"
#include <iostream>
using namespace std;
void MP3::ReadData()
{
    cout << "MP3传输数据" << endl;
}

Computer.h

#pragma once
#include "IUSB.h"
class Computer
{
public:
    IUSB* usb1;
};

Lesson28_练习题.cpp

#include <iostream>
using namespace std;
#include "Person.h"
#include "Home.h"
#include "Car.h"

#include "Computer.h"
#include "StorageDevice.h"
#include "MP3.h"
int main()
{
    #pragma region 练习题一
    /*人、汽车、房子都需要登记,人需要到派出所登记,汽车需要去车管所登记,房子需要去房管局登记
    使用接口实现登记方法*/

    IRegister* person = new Person();
    person->Register();
    delete person;
    person = nullptr;

    IRegister* car = new Car();
    car->Register();
    delete car;
    car = nullptr;

    IRegister* home = new Home();
    home->Register();
    delete home;
    home = nullptr;

    //派出所登记
    //车管所登记
    //房管局登记

    #pragma endregion

    #pragma region 练习题二
    /*麻雀、鸵鸟、企鹅、鹦鹉、直升机、天鹅
    直升机和部分鸟能飞
    鸵鸟和企鹅不能飞
    企鹅和天鹅能游泳
    除直升机,其它都能走
    请用面向对象相关知识实现*/
    #pragma endregion

    #pragma region 练习题三
    /*多态来模拟移动硬盘、U盘、MP3查到电脑上读取数据
    移动硬盘与U盘都属于存储设备
    MP3属于播放设备
    但他们都能插在电脑上传输数据
    电脑提供了一个USB接口
    请实现电脑的传输数据的功能*/
    Computer* computer = new Computer();

    StorageDevice* hd = new StorageDevice("移动硬盘");
    StorageDevice* ud = new StorageDevice("U盘");
    MP3* mp3 = new MP3();

    computer->usb1 = hd;
    computer->usb1->ReadData();

    computer->usb1 = ud;
    computer->usb1->ReadData();

    computer->usb1 = mp3;
    computer->usb1->ReadData();

    //移动硬盘传输数据
    //U盘传输数据
    //MP3传输数据


    //没有插入任何设备(对象)
    computer->usb1 = nullptr;

    //如果这些设备不想用了 直接移除
    delete hd;
    hd = nullptr;

    delete ud;
    ud = nullptr;

    delete mp3;
    mp3 = nullptr;

    #pragma endregion

}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏