你有没有注意到,在面试中,同样陈词滥调的问题总是被反复问出来?
我相信你知道我的意思。
例如:
你认为五年后自己会是什么样子?
或者,更糟糕的是:
你认为你最大的弱点是什么?
饶了我吧。我认为回答这个问题是一个很大的弱点!无论如何,这不是我的观点。
尽管这些问题可能微不足道,但它们很重要,因为它们提供了关于你的线索。你现在的心态,态度,观点。
回答的时候,你应该小心,因为你可能会透露一些你未来后悔的事情。
今天我想谈谈编程界类似的问题:
面向对象编程的主要原则是什么?
在这个问题上,我一直持两种观点。这是一个经常被问到的话题,你不能让自己不知道。
初级和入门级开发人员通常必须回答这个问题。因为这是一个简单的方法让面试官告诉你三件事:
1、应聘者为这次面试做准备了吗?
如果你立即听到一个答案,你会得到加分——这表明你态度严肃。
2、候选人是否通过了教程阶段?
理解面向对象编程(OOP)的原则表明,您已经超越了从教程中复制和粘贴—您已经从更高的角度看待问题。
3、应聘者的理解力是深还是浅?
在这个问题上的能力水平往往等于在大多数其他科目上的能力水平。相信我。
面向对象编程的四个原则是封装、抽象、继承和多态性。
这些话对初级开发人员来说可能听起来很可怕。维基百科中复杂而冗长的解释有时会使混乱加倍。
这就是为什么我要对这些概念给出一个简单、简短和清晰的解释。这听起来像是你向孩子解释的事情,但我真的很想在面试时听到这些答案。
封装
假设我们有一个程序。根据程序中定义的规则,它有几个逻辑上不同的对象,它们彼此通信。
当每个对象在类中保持其状态私有时,就可以实现封装。其他对象不能直接访问此状态。相反,它们只能调用一个公共函数列表——称为方法。
因此,对象通过方法管理它自己的状态——除非显式允许,否则任何其他类都不能接触它。如果希望与对象通信,应该使用提供的方法。但是(默认情况下),您不能更改状态。
假设我们正在创建一个小型的模拟人生游戏。有很多人和一只猫。他们互相交流。我们想要应用封装,所以我们将所有“cat”逻辑封装到一个cat类中。它可能是这样的:
[caption id="attachment_42163" align="aligncenter" width="800"]
你可以喂猫。但是你不能直接改变猫的饥饿程度。[/caption]
在这里,猫的“状态”是私人变量情绪、饥饿和精力。它还有一个私有方法meow()。它可以随时调用它,其他类不能告诉猫何时喵喵叫。
它们可以在公共方法sleep()、play()和feed()中定义。它们中的每一个都以某种方式修改内部状态,并可能调用meow()。因此,在私有状态和公共方法之间建立了绑定。
这是封装。
抽象
抽象可以看作是封装的自然扩展。
在面向对象的设计中,程序通常非常大。而且,不同的对象之间有很多通信。因此,多年来保持这样的大型代码库(在此过程中进行了更改)是很困难的。
抽象是一个旨在缓解这个问题的概念。
应用抽象意味着每个对象只应该公开使用抽象的高级机制来使用它。
这种机制应该隐藏内部实现细节。它应该只显示与其他对象相关的操作。
试想——一台咖啡机。它做了很多事情,在引擎盖下发出古怪的声音。但是你要做的就是把咖啡豆倒进去,然后按下按钮。
最好这种机制应该易于使用,并且很少随时间变化。可以把它看作是一组公共方法,任何其他类都可以调用这些方法,而不需要“知道”它们是如何工作的。
另一个现实生活中的抽象例子?
想想你是如何使用手机的:
[caption id="attachment_42164" align="aligncenter" width="796"]
手机很复杂。但是使用起来很简单。[/caption]
你只需要几个按钮就可以和手机互动。手机内部是怎么回事?您不必知道——实现细节是隐藏的。你只需要知道一小部分动作。
实现更改——例如,软件更新——是一种不影响您使用的抽象。
继承
好的,我们看到了封装和抽象如何帮助我们开发和维护一个大的代码库。
但是你知道OOP设计中另一个常见的问题是什么吗?
对象通常非常相似。它们有共同的逻辑。但它们并不完全相同。
那么,我们如何重用公共逻辑并将惟一的逻辑提取到一个单独的类中呢?实现这一点的一种方法是继承。
它意味着通过从另一个(父)类派生来创建(子)类。这样,我们就形成了一个层次结构。
子类重用父类的所有字段和方法(公共部分),并且可以实现自己的(惟一部分)。
例如:
[caption id="attachment_42165" align="aligncenter" width="800"]
私人教师是一种教师类型。任何老师都是人类[/caption]
如果我们的项目需要管理公立和私立教师,以及其他类型的人,比如学生,我们可以实现这个类层次结构。
这样,每个类只添加它所必需的内容,同时将公共逻辑重用到父类中。
多态性
我们来看看最复杂的单词!多态性在希腊语中是“多种形状”的意思。
因此,我们已经知道了继承的力量,并愉快地使用它。但问题来了。
假设我们有一个父类和几个继承自它的子类。有时我们想要使用一个集合——例如一个列表——它包含所有这些类的混合。或者我们为父类实现了一个方法——但是我们也想为子类使用它。
这可以通过使用多态性来解决。
简单地说,多态性提供了一种方法来使用与其父类完全相同的类,因此不会与混合类型混淆。但是每个子类都保留它们自己的方法。
这通常通过定义要重用的(父)接口来实现。它概述了一些常见的方法。然后,每个子类实现自己版本的这些方法。
每当集合(如列表)或方法期望父方法的实例(其中概述了公共方法)时,该语言负责评估公共方法的正确实现—不管传递的是哪个子方法。
看一下几何图形实现的草图。它们重用一个公共接口来计算表面积和周长:
[caption id="attachment_42167" align="aligncenter" width="800"]
三角形、圆和矩形现在可以在同一集合中使用[/caption]
让这三个图继承父图接口,可以创建混合三角形、圆形和矩形的列表。把它们当作相同类型的对象。
然后,如果这个列表试图计算元素的表面,就会找到并执行正确的方法。如果元素是三角形,则调用三角形的CalculateSurface()。如果它是一个圆,那么调用cirlce的CalculateSurface()。等等。
如果你有一个函数通过使用它的参数来操作一个图形,你不需要定义它三次——一次定义一个三角形,一个圆,一个矩形。
您可以定义它一次,并接受一个图形作为参数。无论传递的是三角形、圆形还是矩形——只要它们实现CalculateParamter(),它们的类型就无关紧要。
我希望这能有所帮助。你可以在面试中直接使用这些完全相同的解释。
如果你发现有些东西仍然难以理解,请在下面的评论中提出。
接下来是什么?
准备好回答一个有史以来最经典的面试问题是很好的——但有时你永远不会接到面试的电话。
接下来,我将关注雇主希望在初级开发人员身上看到什么,以及在求职时如何从人群中脱颖而出。
敬请期待。