深入浅出之抽象与非抽象
一、虚函数&纯需函数
虚函数 是在基类中使用关键字 virtual 声明的函数。在派生类中重新定义基类中定义的虚函数时,会告诉编译器不要静态链接到该函数。
我们想要的是在程序中任意点可以根据所调用的对象类型来选择调用的函数,这种操作被称为动态链接,或后期绑定。
class Shape {protected:int width, height;public:Shape( int a=0, int b=0){width = a;height = b;}virtual int area(){cout << "Parent class area :" <<endl;return 0;}
};
纯虚函数
您可能想要在基类中定义虚函数,以便在派生类中重新定义该函数更好地适用于对象,但是您在基类中又不能对虚函数给出有意义的实现,这个时候就会用到纯虚函数。
virtual 返回值类型成员函数名(参数表)=0;
class Shape {protected:int width, height;public:Shape( int a=0, int b=0){width = a;height = b;}// pure virtual functionvirtual int area() = 0;
};
= 0 告诉编译器,函数没有主体,上面的虚函数是纯虚函数。
虚函数和纯虚函数有以下所示方面的区别。
(1)类里如果声明了虚函数,这个函数是实现的,哪怕是空实现,它的作用就是为了能让这个函数在它的子类里面可以被覆盖,这样的话,这样编译器就可以使用后期绑定来达到多态了。纯虚函数只是一个接口,是个函数的声明而已,它要留到子类里去实现。
(2)虚函数在子类里面也可以不重载的;但纯虚函数必须在子类去实现,这就像Java的接口一样。通常把很多函数加上virtual,是一个好的习惯,虽然牺牲了一些性能,但是增加了面向对象的多态性,因为很难预料到父类里面的这个函数不在子类里面不去修改它的实现。
(4)带纯虚函数的类叫虚基类,这种基类不能直接生成对象,而只有被继承,并重写其虚函数后,才能使用。这样的类也叫抽象类。抽象类和大家口头常说的虚基类还是有区别的,在C#中用abstract定义抽象类,而在C++中有抽象类的概念,但是没有这个关键字。抽象类被继承后,子类可以继续是抽象类,也可以是普通类。
二、抽象类
包含纯虚函数的类称为抽象类。由于抽象类包含了没有定义的纯虚函数,所以不能定义抽象类的对象。
在C++中,我们可以把只能用于被继承而不能直接创建对象的类设置为抽象类(Abstract Class)。
带有纯虚函数的类称为抽象类。抽象类是一种特殊的类,它是为了抽象和设计的目的而建立的,它处于继承层次结构的较上层。抽象类是不能定义对象的,在实际中为了强调一个类是抽象类,可将该类的构造函数说明为保护的访问控制权限。
抽象类的主要作用是将有关的组织在一个继承层次结构中,由它来为它们提供一个公共的根,相关的子类是从这个根派生出来的。
抽象类刻画了一组子类的操作接口的通用语义,这些语义也传给子类。一般而言,抽象类只描述这组子类共同的操作接口,而完整的实现留给子类。
抽象类只能作为基类来使用,其纯虚函数的实现由派生类给出。如果派生类没有重新定义纯虚函数,而派生类只是继承基类的纯虚函数,则这个派生类仍然还是一个 抽象类。如果派生类中给出了基类纯虚函数的实现,则该派生类就不再是抽象类了,它是一个可以建立对象的具体类了。
抽象类的规定
(1)抽象类只能用作其他类的基类,不能建立抽象类对象。
(2)抽象类不能用作参数类型、函数返回类型或显式转换的类型。
(3)可以定义指向抽象类的指针和引用,此指针可以指向它的派生类,进而实现多态性。
class AbstractCalculator
{
public:virtual int getResult() = 0;virtual void setOperatorNumber(int a, int b) = 0;};//加法计算器类 一个类只做一件事
class PlusCalculator :public AbstractCalculator
{
public:virtual void setOperatorNumber(int a, int b){this->mA = a;this->mB = b;}virtual int getResult(){return mA + mB;}
public:int mA;int mB;
};//减法计算器类
class MinuteCalculator :public AbstractCalculator
{
public:virtual void setOperatorNumber(int a, int b){this->mA = a;this->mB = b;}virtual int getResult(){return mA - mB;}
public:int mA;int mB;
};//乘法计算器类
class MultiplyCalculator :public AbstractCalculator
{
public:virtual void setOperatorNumber(int a, int b){this->mA = a;this->mB = b;}virtual int getResult(){return mA * mB;}
public:int mA;int mB;
};int main(void)
{AbstractCalculator* caculator = new PlusCalculator;calculator->setOperatorNumber(10, 20);cout << calculator->getResult() << endl;delete calculator;return 0;
}
如果定义如下是错误的
AbstractCalculator* caculator = new AbstractCalculator; //错误
三、抽象类与非抽象类
抽象类与非抽象类的区别:
1、抽象类可以被继承但不能被实例化(可以引用子类实例化对象),子类继承自抽象类后必须实现该类的所有抽象方法;
2、抽象类中可以有抽象方法和非抽象方法,非抽象类不能有抽象方法,抽象方法一定要被子类重写,而其他方法没要求。
四、抽象类与接口
接口描述了类的行为和功能,而不需要完成类的特定实现。
C++ 接口是使用抽象类来实现的,抽象类与数据抽象互不混淆,数据抽象是一个把实现细节与相关的数据分离开的概念。
如果类中至少有一个函数被声明为纯虚函数,则这个类就是抽象类。纯虚函数是通过在声明中使用 "= 0" 来指定的,如下所示:
class Box
{public:// 纯虚函数virtual double getVolume() = 0;private:double length; // 长度double breadth; // 宽度double height; // 高度
};
抽象类和接口的区别:
1、抽象类中可以有实现成员(非抽象方法),而接口中的方法只有声明没有实现;
2、抽象类中可以有字段,接口中不能有字段,但可以有属性;
3、抽象类的成员可以使用公有或其他修饰符,接口中成员是隐式公有的,不需要修饰;
4、抽象类是概念的抽象,接口注重行为,抽象类不支持多重继承,而一个类可以实现多个接口。
五、抽象方法
抽象方法,这种方法只声明返回的数据类型,方法名称和所需要的参数,没有方法体,也就是说抽象方法只需要声明而不需要事先,当一个方法为抽象方法时,意味着这个方法必须被子类的方法所重写,否则其子类的该方法仍然是abstract的,而这个子类也必须是抽象的,即声明为abstract。
参考
- C++ 抽象类
- C#中抽象类和接口
- 抽象类和抽象方法总结
深入浅出之抽象与非抽象相关推荐
- Java 设计模式 Day1 之面向抽象原则:抽象(abstract)类的设计与应用分析
文章目录 前言 一.抽象(abstract)类的设计要点 二.抽象类的应用实例 2.1.创建一个抽象类 2.2.创建抽象类非抽象子类 2.3.通过上转型对象调用子类方法 总结 前言 面向抽象原则是面向 ...
- java 抽象数据类型_java抽象数据类型
抽象数据类型 抽象数据类型是描述数据结构的一种理论工具.在介绍抽象数据类型之前我们先介绍一 下数据类型的基本概念. 数据类型(data type)是一组性质相同的数据元素的集合以及加在这个集合上的一组 ...
- php ast 抽象语法树,抽象语法树(AST)
抽象语法树入门到放弃? 抽象语法树(Abstract syntax tree AST)在计算机科学中,抽象语法和抽象语法树其实是源代码的抽象语法结构的树状表现形式 为什么是抽象的? 前端工程化,离不了 ...
- 计算机科学中抽象的作用,抽象释义
在计算机科学中,抽象释义是基于在有序集合特别是格上的单调函数,计算机程序的语义的可靠逼近理论.它可以被看作对计算机程序的部分执行,获取关于它的语义信息(比如,控制结构.信息流)而不进行所有计算. 它的 ...
- scala java抽象理解_scala – 抽象覆盖如何在Java代码方面起作用?
它来了: 它简短,抽象覆盖def m()允许从方法调用super.m()并且当一个特征在所有其他类型之后混合时,这个超级调用动态地代替类型创建,例如 trait Printer { def print ...
- java 反射抽象_Java实现抽象工厂模式+java的反射的机制
Java的反射机制: JAVA反射机制是就是运行的状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法 ...
- 简单工厂、工厂方法、抽象工厂、抽象工厂加简单工厂
简单工厂模式:简单工模式时类的创建模式,又叫做静态工厂方法(static Factory Method).简单工厂模式是一个工厂对象决定创建出哪一种产品类的实例.它存在的目的很简单:定义一个创建对象的 ...
- 设计模式之抽象工厂(抽象工厂 + 反射 + 配置文件)
目录 1.抽象工厂的概念 2.抽象工厂的结构图 3.抽象工厂设计模式的练习示例 4.抽象工厂设计模式的练习示例结构图 5. 抽象工厂 + 反射 + 配置文件 5.1:什么是java的反射机制? 5. ...
- 业务模型抽象与业务流程抽象
1.什么叫业务模型 例: 订单.库存.商品这类的名词都可以称之为模型. 例:订单可能分为实物类订单,服务类订单等,那么这里就提出一个挑战如何进行抽象.一个好的业务模型抽象能使得你的业务模型可复用. 例 ...
最新文章
- 涨姿势 |你所不知道的5 个AR增强现实新趋势
- 云服务器和VPS服务器有什么区别?
- 被丧心病狂的验证码虐过,来感受一下交互体验很好的十款吧
- EhCache 分布式缓存/缓存集群
- java字节码提取if语句_终于找到了!有了它你就可以读懂字节码了!
- 小白学python需要多久_小白学Python | 你还在说你入不了门吗
- 新手学堂:Linux操作系统的启动步骤说明
- 《C#高效编程》读书笔记04-使用Conditional特性而不是#if条件编译
- linux redis配置文件位置,Linux 安装配置Redis
- LynxFly科研小四轴横空出世,开源,F4,WIFI
- 口腔管理软件DSD微笑设计与正畸头影测量工具组合包简介
- python 实现图像的手绘效果
- Error:java.lang.RuntimeException: Crunching Cruncher dialog_et_bg.9.png failed, see logs
- 我的理想200字计算机工程师,我的理想工程师作文(我的理想是做一名工程师)...
- 数据挖掘算法和实践(二十一):kaggle经典-职场离职率分析案例解读
- 2018年的最后一周,说些心里话
- gb2312简繁转换js兼容各种浏览器
- 关于Floyd算法 和 Dijkstra算法
- SpringBoot框架的优点
- Quorum (分布式系统)
热门文章
- boost::sort模块实现spreadsort 反向字符串排序示例
- boost::process::env相关的测试程序
- boost::log模块记录多个线程的示例
- boost::graph模块实现广度优先搜索算法的使用示例
- gdcm::ImageChangePhotometricInterpretation的测试程序
- ITK:仅将过滤器应用于图像的指定区域
- VTK:可视化算法之PlateVibration
- VTK:可视化算法之FindCellIntersections
- OpenCV均值移位(Meanshift)和Camshift算法
- C语言数组中找到第一个重复元素的算法(附完整源码)