这是技术面试过程中经常问的问题,真要彻底的讲明白,不是一件很容易的事情。可以简单的用C语言和C++两种语言的本质区别来具体解释,首先从设计模式来讲面向对象更加容易形成框架特性,现在高级语言基本上都支持面向对象,像java,python都是这个样子。
从事编程十几年两种思想的编程语言都有一些涉猎,整体给人感觉面相对对象更加容易理解,面向对象更加抽象,现在就一些具体的特性做一个大概的了解。
如何理解面向过程
面向过程和大家正常是思维模式接近,把一个问题按照从左到右,从上到下的解决方案分解成N个小步骤然后挨个去执行,说的再抽象一点就是模块化,具体实现通过函数来完成,函数里面又可以调用函数,最终功能点就是被无数个函数来完成。
从代码逻辑上分析,主函数main函数下面分成几个大的功能函数,这几个函数又被分解成无数个小函数完成,稍微复杂点开启多个线程异步处理一些功能,基本上就是面向过程的全过程了,非常容易理解,底层的功能模块也能别的功能模块共用,不能讲面向过程没有共用性,只不过相对框架性看起来差些,linux内核绝大部分代码都是C语言完成,如果没有框架性不可能这么稳定的运行,也正是这么灵活的功能模块调用,早就了高效,所以在某些领域C语言依然是编程首先,同时也是基石,现在很多编程语言的底层都是C语言来完成的。
如果能用C语言的框架把一个系统构建的十分完善并且具备很强的扩展性,一定是编程的高手,这主要靠内在功底把零散的东西有机的结合成一种框架,不像面向对象自带抽象模型体系。
如何理解面向对象
面向对象在模式上和面向过程截然不同,面向对象是先抽象一个模型,然后把这个模型实例化来使用,这个抽象模型就是大家经常听到的类的概念,类并不能直接去使用,而是需要直接实例化,所以做了很多年面向过程的老程序员,发现面向对象类必须实例化,特别是想调用里面其中的一个方法的时候,还需要拿到对方的实例,然后才能直接去调用,放在面向过程的编程里面是可以直接功能函数。
面向对象里面的类,其实是面向对象里面结构体的延伸,把这个概念放大化了。类主要是两个部分构成,属性和方法,属性就是变量,方法就是功能模块。当然面向对象最主要的概念是把事物抽象化,举个例子,把各种动物抽象成一个类,常见的狗,鸡鸭鹅等共有的属性,都有能走动的动作,都有脚属性,但不同的动物数量不一样,抽象成一个动物类,如果要弄一个狗的类首先继承一个动物类,并且把动物基本的特性继承过来,如果觉得有些方法差异太大就覆盖掉,同时增加新的特性封装成一个新的类,然后实例化进行具体使用,还可以同时继承多个类,拿到共性的方法或者属性,这样子能很好的继承已经有的功能,特别积累并且继承以前的功能。
面向对象在代码量上会比面向过程的会少一些,毕竟有些功能方法可以直接继承过来用,所以开发面向对象的程序员切换到面向过程会觉得特别不舒服,有些共有的方法直接继承过来去用非常顺其自然,面向过程调用更加突兀或者直接一点。面向对象在解决复杂是逻辑上更加占据一定的优势,而且越用越有感觉。
如何理解面向对象的三个特性?
1.封装性
就是把属性和方法都放在一个类里面,而且还可以通过访问类的权限属性给区分开,更加安全,不想要释放的功能,直接搞成私有机制,正好符合软件架构里面高内聚低耦合,自己内部的事情就不要暴露出来,外部接口尽量简单,所以在设计上就符合软件设计的理念,封装性还具有安全性了,不想让外部访问的时候可以屏蔽。
2.继承性
就是把之前已经实现好的代码或者方法通过继承的方法拿过来使用,能节省大量的代码量,符合代码设计里面的继承优秀代码特性,而且写好的类还能给后来的人继续使用,面向对象语言更能形象的称之为站在巨人的肩上
3.多态性
由于可以继承多个类,能够组合成多种特性,但多态的关键是覆盖,就是同一个方法可以用不同的方式去实现,展现出多态性。
虽然看似这些概念很简单,说起来要比较容易,还是要真正在项目中去体现,真正通过代码来验证自己的想法,通过大型的项目实战再回归研究这些基本的概念,就会对这个设计者充满无线的钦佩。
在编程语言中,面向过程与面向对象的区别在哪?优缺点在哪?
面向对象与面向过程的区别
首先,面向对象编程语言和面向过程编程语言都是操作计算机的方式,从本质上来说也都是操作计算机执行任务的工具,只是方式上的不同而已。
面向过程编程语言故名思议,以业务流程为考虑问题的出发点,从上到下按照解决问题的流程来组织代码结构,把功能封装成函数,然后依次调用就可以了。所以,面向过程的编程方式往往具有更为清晰的代码流程。面向过程的编程在早期业务逻辑比较单一的时期是非常适合的,而且面向过程的编程语言往往有更高的执行效率,典型的代表就是C语言。当前,C语言在嵌入式开发、操作系统开发领域依然具有广泛的应用。
随着软件开发的复杂化,软件编程需要解决的逻辑问题越发复杂,此时面向对象编程语言就出现了,面向对象语言的主要特点是“抽象”,形成了类、对象、封装、继承、多态等一系列面向对象的概念,这些概念的使用使得开发大型的业务逻辑系统更加方便和可行了。Java是典型的面向对象编程语言,目前也是IT行业内应用最为广泛的编程语言之一,在Web开发、大数据开发、后端开发和Android开发领域都有大量的应用。
简单的说,面向过程以解决问题的单一思路为出发点,而面对对象则以多角度解决问题为出发点,所以面向对象的编程要更加复杂一些。从学习的角度出发,学习面向过程的编程语言要稍微容易一些,毕竟函数式编程更容易理解。在学习面向对象编程语言的时候,在学习的初期会具有一定的困难,困难在于要理解一系列抽象概念,所以不少人都说,学习面向对象编程就是学习“抽象”。
我从事互联网行业多年,目前也在带计算机专业的研究生,主要的研究方向集中在大数据和人工智能领域,我会陆续写一些关于互联网技术方面的文章,感兴趣的朋友可以关注我,相信一定会有所收获。
如果有互联网方面的问题,或者考研方面的问题,都可以咨询我,谢谢!
老师说C语言是面向过程的编程语言,它能使用面向对象编程吗?如何使用?
。
其实,“面向过程”和“面向对象”只是程序开发中的一种方法,或者说一种思想,大多数现代高级编程语言都能使用这两种编程思想,C语言当然也不例外。
只不过,有些编程语言在语法上支持“对象”,而C语言则没有原生的“对象”语法。不过借助于灵活的指针和结构体语法,在C语言程序开发中使用“面向对象”思想也是很简单的。
malloc() 和 free() 函数
鉴于题主可能是C语言初学者,在开始讨论如何使用C语言进行“面向对象”开发之前,先介绍两个新函数——malloc() 和 free() 。
如果题主看过我之前文章的话,应该明白C语言程序每调用一次函数,系统就会在栈中分配一块栈帧给被调用函数,当函数执行完毕后,这部分栈帧就自动被系统收回了。
malloc() 函数的作用是申请一块指定大小的内存,它的C语言原型如下,成功时返回这块内存的首地址,失败时返回 NULL。
C语言程序中函数的局部变量占用的内存,是函数运行时,自动在其所属栈帧中分配的,所以局部变量会随着函数结束释放。不过,malloc() 向系统申请的内存在堆区里,这部分内存不会随着函数的退出自动释放,需要程序员自己使用 free() 函数释放:
以上这几行C语言代码的意思是向系统申请 5 字节的内存,如果申请成功,就把它释放。
如果在C语言程序退出之前,只 malloc() 而不 free(),程序占用的内存会越来越多,直到最后崩溃退出。这种情况,程序员习惯称为“内存泄漏”。
使用C语言进行“面向对象”编程
相当一部分程序员看不起C语言是因为他们觉得C语言没有“对象”。现在,我们尝试给C语言找一个“对象”。请看:
因为C语言不支持原生的“类”语法,所以我们使用结构体模拟了一个 class,定义了一个“FATHER 类”,它有成员函数 hello()。
上述C语言代码又定义了一个“SON 类”,它有成员函数 hello(),也有成员变量 count(),还有一个“父类”father。接下来,定义“FATHER类”和“SON类”的 hello 函数,相关C语言代码如下:
如何让这两个函数与我们定义的“类”产生联系呢?我们定义“构造函数”:
上述C语言代码首先使用 malloc() 为 son 在堆中申请一块内存,这保证了 son 在程序结束之前都不会被释放。同样的,为 father 也申请了一块内存。
接着,把它们各自的函数传递给结构体里面定义的函数指针,这样便定义好了“类”son。有了构造函数,再来定义“析构函数”,相关C语言代码如下:
析构函数的主要作用就是释放 malloc() 的内存,防止内存泄漏。至此,我们就使用C语言实现了“类”的封装,测试一下:
上述C语言代码是典型的“面向对象”风格:程序使用 SON 类实例化了一个 son 对象,son 调用了自己的成员函数,也调用了从“父类”继承而来的函数。编译并执行这段C语言代码,发现输出与预期一致。
应该注意的是,从表达式 son->hello(son) 可以看出,C语言没有类的支持,所以需要显式的把 son 指针传给 hello。但是,“father类”和“son类”里都可以使用 hello 做函数名,这说明C语言的“类”也对封装有很好的效果。
欢迎在评论区一起讨论,质疑。文章都是手打原创,每天最浅显的介绍C语言、linux等嵌入式开发,喜欢我的文章就关注一波吧,可以看到最新更新和之前的文章哦。