C++中接口与抽象类

(一)接口和抽象类的概念不一样.接口是对动作的抽象, 抽象类是对根源的抽象.

抽象类表示的是, 这个对象是什么. 接口表示的是, 这个对象能做什么. 比如,男人,女人,这两个类(如果是类的话……),他们的抽象类是人。说明,他们都是人。

人可以吃东西,狗也可以吃东西,你可以把“吃东西”定义成一个接口,然后让这些类去实现它.

所以,在高级语言上,一个类只能继承一个类(抽象类)(正如人不可能同时是生物和非生物),但是可以实现多个接口(吃饭接口、走路接口)。

第一点. 接口是抽象类的变体,接口中所有的方法都是抽象的。而抽象类是声明方法的存在而不去实现它的类。
第二点. 接口可以多继承,抽象类不行
第三点. 接口定义方法,不能实现,而抽象类可以实现部分方法。
第四点. 接口中基本数据类型为static 而抽类象不是的。

当你关注一个事物的本质的时候,用抽象类;当你关注一个操作的时候,用接口。


抽象类的功能要远超过接口,但是,定义抽象类的代价高。因为高级语言来说(从实际设计上来说也是)每个类只能继承一个类。在这个类中,你必须继承或编写出其所有子类的所有共性。虽然接口在功能上会弱化许多,但是它只是针对一个动作的描述。而且你可以在一个类中同时实现多个接口。在设计阶段会降低难度的。

(二)

接口的定义:接口的作用,就是提供一个与其他系统交互的方法。其他系统无需了解你内部细节,并且也无法了解内部细节,只能通过你提供给外部的接口来与你进行通信。根据c++的特点,我们可以采用纯虚函数的方式来实现。这样做的好处是能够实现封装和多态。

class IPerson
{
public:
    IPerson() {};
    virtual ~IPerson(){};
    virtual void SetName(const string &strName)=0;
    virtual const string GetName()=0;
    virtual void Work()= 0;
};
接口实现:实现接口是通过继承接口的子类来实现的,不同的子类可以实现不同效果,即使所谓多态

class CTeacher: public IPerson
{
public:
    CTeacher() {};
    virtual ~CTeacher(){};
    string m_strName;
    void SetName(const string &strName);
    const string GetName();
    void Work();

};
void CTeacher::SetName(const string &name)
{
    m_strName = name;
}
const string CTeacher::GetName()
{
    return m_strName;
}

void CTeacher::Work()
{
    cout <<"I am teaching!"<<endl;
}

(三)

(1)纯虚函数定义.
        纯虚函数是在基类中声明的虚函数,它在基类中没有定义,但要求任何派生类都要定义自己的实现方法。在基类中实现纯虚函数的方法是在函数原型后加“=0”

(2)引入原因:
1、为了方便使用多态特性,我们常常需要在基类中定义虚拟函数。
2、在很多情况下,基类本身生成对象是不合情理的。例如,动物作为一个基类可以派生出老虎、孔雀等子类,但动物本身生成对象明显不合常理。
     为了解决上述问题,引入了纯虚函数的概念,将函数定义为纯虚函数(方法:virtual ReturnType Function()= 0;),则编译器要求在派生类中必须予以重载以实现多态性。同时含有纯虚拟函数的类称为抽象类,它不能生成对象。这样就很好地解决了上述两个问题。

(3)相似概念:
1、多态性
    指相同对象收到不同消息或不同对象收到相同消息时产生不同的实现动作。C++支持两种多态性:编译时多态性,运行时多态性。
    a.编译时多态性: 通过函数重载和运算符重载来实现的。
    b 运行时多态性:通过继承和虚函数来实现的。
2、虚函数
    虚函数是在基类中被声明为virtual,并在派生类中重新定义的成员函数,可实现成员函数的动态重载
    纯虚函数的声明有着特殊的语法格式:virtual 返回值类型成员函数名(参数表)=0;

     请注意,纯虚函数应该只有声明,没有具体的定义,即使给出了纯虚函数的定义也会被编译器忽略。

3、抽象类

     包含纯虚函数的类称为抽象类。由于抽象类包含了没有定义的纯虚函数,所以不能定义抽象类的对象。
     在C++中,我们可以把只能用于被继承而不能直接创建对象的类设置为抽象类(Abstract Class)。

          之所以要存在抽象类,最主要是因为它具有不确定因素。我们把那些类中的确存在,但是在父类中无法确定具体实现的成员函数称为纯虚函数。纯虚函数是一种     特殊的虚函数,它只有声明,没有具体的定义。抽象类中至少存在一个纯虚函数;存在纯虚函数的类一定是抽象类。存在纯虚函数是成为抽象类的充要条件

//基类:
class A
{
public:
    A();
    void f1();
    virtual void f2();
    virtual void f3()=0;
    virtual ~A();
};
//子类:
class B : public A
{
public:
    B();
    void f1();
    void f2();
    void f3();
    virtual ~B();
};
//主函数:
int main(int argc, char* argv[])
{
    A *m_j=new B();
    m_j->f1();
    m_j->f2();
    m_j->f3();
    delete m_j;
    return 0;
}
/*
f1()是一个普通的重载.
调用m_j->f1();会去调用A类中的f1(),它是在我们写好代码的时候就会定好的.因为f1()不是虚函数,不会动态绑定
也就是根据它是由A类定义的,这样就调用这个类的函数.
f2()是虚函数.
调用m_j->f2();会调用m_j中保存的对象中,对应的这个函数.这是由于new的B对象.
f3()与f2()一样,只是在基类中不需要写函数实现.
*/



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值