理解抽象类与接口

抽象类:  abstract Class

Class Animal

{

public:

    virtual void getShoutSound() = 0; // 纯虚函

};

Class Cat: public Animal

{

public:

    virtual void getShoutSound()

{

    //…

}

};

      你会发现Animal类根本没可能实例化,可以说一只猫长什么样,但是不能说一只动物长什么样。

      动物是是一个抽象的名词,没有具体对象与之对应。

  1. 抽象类不能实例化;
  2. 抽象方法时必须被子类重写的方法;(不重写,它存在有什么意义呢?)
  3. 如果类中包含抽象方法,那么类就必须定义为抽象类,不论是否还包含其他一般方法。

  抽象类拥有尽可能多的共同代码,拥有尽可能少的数据。

  抽象类其实就是一种规范、协议,它提供一个继承的出发点,当设计一个新的抽象类的时候,其一定是用来继承的,其继承类必须遵循这个规范、协议。在一个以继承关系形成的等级结构里面,树叶节点应当是具体类,而树枝节点均应当是抽象类。

  比如:猫、狗、牛、羊是最后一级,它们是具体类。但是如果有更下一级的波斯猫继承于猫,哈皮狗继承于狗,就需要考虑把猫和狗改成抽象类了。

接口

在动物动还有一类具有特异功能的动物。

我去,动物居然还有特异功能,倒想瞧瞧是什么动物。

比如:机器猫小叮当、美猴王孙悟空、蜘蛛侠等等

呀呀,这都是什么动物啊,根本就是影视剧虚构之物啊!

机器猫会从口袋里变出东西,孙悟空会七十二变,蜘蛛侠会变出蜘蛛丝用来飞檐走壁…

"变出东西"是它们的行为方法,要用到多态,让他们拥有变出东西的能力,而为了具有普遍的意义,干脆让他们具有"变出东西"的行为,这样就可以使用多态了~

但是,但是,不能将"变出东西"的行为放在Animal中去,实际想象,"变出东西"它能使动物的方法吗?显然不能,一般的动物还真没这能力!

但是机器猫、孙悟空、蜘蛛侠这些具有特异功能的动物具有的"变出东西"是它们特殊具备的方法,这就需要新的知识了,那就是借口interface。

接口是把隐式公共方法和属性组合起来,以封装特定功能的一个集合。一旦类实现了接口,类就可以支持接口所指定的所有属性和成员。

声明接口的语法与声明抽象类完全相同,但是不允许提供接口中任何成员的执行方式。

接口不能实例化,不能有构造方法和字段;不能有修饰符,比如public、private等;不能声明虚拟的或者静态的等。

实现接口的类就必须要实现接口中的所有方法和属性。

一个类可以支持多个接口,多个类也可以支持相同的接口。

接口是一种特殊的抽象类。

Interface IChange

{

    String ChangeThing(string strThing);

};

Class MachineCat:public Cat, IChange

{

    

};

类是对对象的抽象;

抽象类是对类的抽象;

接口是对行为的抽象。

如果行为跨越不同类的对象,可以使用接口;

对于一些相似类对象,用继承抽象类。

举个例子:猫狗牛羊它们其实都是动物,它们之间有许多相似之处,所以让它们去继承"动物"这个抽象类;而飞机、麻雀、超人是完全不相关的类,机器猫是动漫角色,孙悟空是神话人物,这也是不相关的类,它们都有共同点,前三个都会飞,后两个会变东西,所以此时让它们去实现相同的接口来达到我们的设计目的就很合适了。

从设计角度讲,抽象类是从子类中发现了公共的东西,泛化出父类,然后子类继承父类,而接口是根本不知道子类的存在,方法如何实现还不确定,预先声明,等着子类去实现

 

什么是重构?

我们设计的时候,可能先是设计一个Cat类,然后再有一个Dog类,观察后发现它们有类似之处,于是泛化出Animal类,这也体现了敏捷开发的思想,通过重构改善既有代码的设计。

事实上,只有Cat类的时候,你就可以去设计一个Animal类,这就极有可能会成为过度设计了。

所以说,抽象类往往是通过重构的来的,如果事先意识到多种分类的可能,事先就设计出抽象类也是完全可以的。

对比一下

  接口                              抽象类

多继承             支持                             不支持

类型限制            没有                              有,只能是引用类型

方法实现            继承类型中必须给出方法实现        继承类中可以不给出

扩展性             比较麻烦                          相对比较灵活

多层继承            比较麻烦,需要借助虚函数           比较灵活

猜你喜欢

转载自www.cnblogs.com/MakeView660/p/9294045.html