注意到了吗,在职业面试中,那些老掉牙的问题总被一遍又一遍地重复。
你一定知道我想说什么。
比如:
你五年之内的规划是什么?
更有甚者:
你觉得你最大的缺点是什么?
呃,停一下。我觉得不会回答这个问题是我的一个缺点。不管怎样,这不是我的观点。
尽管这些问题很琐碎,但它们会让别人对你的心理状态、态度、观点有一些初步了解,所以它们很重要。
你必须谨慎地回答这些问题,否则以后会后悔的。
今天我想谈一谈编程世界里一种相似的问题:面向对象程序设计的主要原则是什么?
在这个问题上我是中立的。这个话题会被频繁地提起,所以你必须知道如何应对。
新手们通常都会面对这个问题,因为面试官可以从中轻松地看出三件事:
1.候选人是否为面试做了准备?
如果听到了不假思索的回答,这表明他的态度端正,会是一个加分点。
2.候选人是否通过了入门阶段?
理解面向对象程序设计的原则,表明你已经能够从更高的层面来看问题,而不是局限于从教程中复制粘贴那个层面。
3.候选人的理解是深刻还是肤浅?
相信我,在这个问题上表现出来的能力级别,通常等价于在其他大部分学科上的能力级别。
面向对象程序设计的四个原则是封装、抽象、继承和多态。
对于一个新手程序员,这些词汇也许听起来有点吓人,而维基百科里对此复杂的、冗长的解释有时会让程序员的焦虑加倍。
所以,我要给每个概念一个简短清晰的解释。也许我的解释听起来有点过于简单,就像讲给小孩子听的那样,但如果我是面试官,听到这种回答我会很满意。
封装
假设我们有一个程序。根据程序定义的规则,它在逻辑上有一些不同的对象,并且这些对象彼此之间会相互交流。
在一个类中,当每个对象的状态保持相对孤立,就实现了封装。其余的对象并不能观察到这个对象的状态。他们能做到的只有调用一些被称作“方法”的通用功能。
因此,对象使用方法掌控着自己的状态,除非明确允许,没有其他人可以接触到它。如果你想和某个对象交流,你需要使用提供的方法。但在默认情况下,你无法改变对象的状态。
假设我们要构建一个小型的模拟游戏,游戏里有人有猫,他们之间可以交流。如果我们想使用封装,就得把所有“猫”逻辑封装到猫类中。看上去是这样的:
在这里,猫的饥饿与能量状态是私有变量。它也有一个私有方法喵()。只要它愿意,就可以随时调用,其他类不能控制猫去喵喵叫。
人们能做的事情被定义在通用方法中,是睡觉(),玩耍(),喂食()。他们都能或多或少地调整内部状态并有可能调用喵()。这样就建立了私有状态和通用方法之间的桥梁。
这就是封装。
抽象
抽象可以被看作封装的自然扩展。
在面向对象的程序设计中,程序通常都很庞大。独立的对象之间能够进行大量的交流。要想在不断的变化中维护这样一个庞大的代码库多年,是很困难的。
抽象是为了简化这个问题而存在的一个概念。
使用抽象表示每个对象只能有一个高等级使用机制。
这个机制应该隐藏内部实现细节,只展现与其他对象相关联的操作。
想想一台咖啡机。它能干许多事情,它的引擎会发出许多古怪的噪音。但你需要做的只是加入咖啡,按个按钮而已。
如果这个机制易于使用,不会随着时间推移有多少变化,就更好了。
抽象在现实生活中还有什么例子?
想想你使用手机的场景:
手机内部结构很复杂,但使用起来却很简单。
你只需要通过几个按钮就能与手机互动。后盖下面的元件在怎样运转?你不需要知道。
执行的细节被隐藏起来了。你需要的只是一组简单的动作。
执行更改,比方说某软件的升级,并不会影响你对抽象的使用。
继承
我们已经知道了封装和抽象是如何帮助我们开发并维系代码库了。
但你知道,在面向对象程序设计中,另一个常见的难题是什么吗?
那就是,对象通常都很相似。它们有共同的逻辑。但它们并不完全相同。呃……
那么我们怎样才能重用这些共同的逻辑,并将其抽取加入独立的类?继承是个好办法。
这表示你从一个(父)类中衍生出另一个(子)类。这样我们就完成了一次继承。
子类再次利用了父类(常规部分)的所有域和方法,并能执行自己的(独特部分)。
例如:
家庭教师是教师的一个种类。任何一个老师都是人类的一个种类。
如果我们的程序需要管理私人教师和公共教师,同时也需要其他种类的人,比如学生,那么我们可以执行这一类。
通过这种方式,每个类再次利用父类的共同逻辑时,就可以只添加自身必需的部分。
多态
现在我们终于来到了最复杂的概念了!
“多态”(Polymorphism)在希腊语中表示“多种形态”的意思。
我们已经知道了继承的力量,并很满意地使用着它。但是,麻烦出现了。
假设我们有一个父类和一些由它衍生出的子类。有时我们会需要一个包含了所有这些类的集合,比如一个列表。或者说我们为父类添加了一个方法,但我们也想让子类使用它。通过使用多态就可以解决这个问题。
简单来说,多态提供了一种完全像使用其父类一样,使用别的类的方式,这样就不会将杂糅在一起的各个类搞混。但是每个子类仍然保留着自己的私有方法。
一般通过定义需要重用的(父)接口来实现。它列出许多通用方法,然后,每个子类装载属于自己的方法的版本。
每当集合(比如列表)或方法需要父类(给出通用方法)的例子,语言就会着重评估通用方法是否正确执行,无论它被传递给了哪个子类。
让我们来看看几何图形实现的草图。它们重用一个用于计算表面积和周长的公共界面。
在同一个集合中,三角形、圆形、矩形可以同时使用。
让这三个图形继承父图形界面,可以创建混合三角形、圆形和矩形的列表。你可以像对待同样类型的对象一样处理它们。
接下来,如果列表尝试计算元素的表面积,正确的方法就会被立刻找到并执行。如果元素是三角形,三角形的计算表面积()就会被调用。如果它是圆形,圆形的计算表面积()就会被调用。以此类推。
如果你能通过参数操作图形,就不需要将三角形、圆形、矩形一个个定义三次。
你可以只定义一次,并把数据留下作为参数。只要实现计算参数(),不管什么形状都无所谓。
我希望这能够对你有所帮助。你可以在面试的时候直接使用这些解释。
原文链接:
https://medium.freecodecamp.org/object-oriented-programming-concepts-21bb035f7260
来源:medium
作者:Alexander Petkov
智能观 编译
—完—
亲爱的朋友:
这篇文章让我想起两件事。
1.一次课堂上,老师说,他在招聘时,经常会问一些很基础的问题。想看看对方是怎么理解的,怎么运用的。
事实上,他经常遇到一些说自己取得了多少成绩,分数多高的学生,但面对基础问题时,大部分只懂背概念,不懂怎么运用。
2.《三傻大闹宝莱坞》中,课堂上老师提问什么机械的概念时,兰彻的回答。
希望本文对你有所帮助。
祝安!
智能观 一米
2018-7-4 于北京中关村
想知道AI加教育领域有哪些最新研究成果?
想要AI领域更多的干货?
想了解更多专家的“智能观”?
请前往:www.智能观.com。
声明:
编译文章旨在帮助读者了解行业新思想、新观点及新动态,为原作者观点,不代表智能观观点。