bra*_*boy 39 c++ java oop inheritance
通常我不想知道OOP的缺点的具体情况,但是当我在最近参加的一次面试中发表争论时,感觉有点奇怪.发给我的问题是告诉我面向对象编程(OOP)的一个缺点.那时,我认为OOP是程序和功能模型之后最成熟的编程水平.所以我回答他说我根本没有看到任何负面消息.
但是面试官说很少,如果他不介意的话,我请他列出一个.他举了一个例子,我不能很好地消化.他说,一个面向对象的模式不严格执行继承规则,并列举卫星/火箭例如当身体各部位会定期瓦解火箭发射过程中去除重量和说,继承不支持这一点.
他的例子对我来说非常奇怪,原因是继承应用于这个例子.
我明白他给出的例子几乎没有任何意义,但我怀疑 -
我们可以在一个理想的面向对象设计中动态地拔掉类层次结构(我对Java有点不可信)吗?
LBu*_*kin 34
仅仅因为你有一把锤子,并不意味着一切都是钉子.
我发现当使用OOP作为编程风格时,许多人经常会混淆何时应用合成与继承.你从面试问题中引用的例子似乎就是这种混淆的一种情况.
有一件事我已经有经验教训的话,当继承是表达一个很好的范例"IS-A"在设计实体之间的关系,它往往更青睐组成,而不是继承.
但是让我们来看看面试官问题的症结所在:OOP什么时候是范式的选择?.
OOP最适合大规模,多开发人员,多模块项目.对于" 小型开发 " - 例如脚本或变换处理,它可能需要大量的开销而不必增加价值.但即使在这种情况下,除非你正在写扔掉的代码,我认为大的解决方案往往是从较小的发展,因此建立早期就关注结构和分离可以节省您以后的悲伤.
最终,OOP编程还需要一定程度的设计严谨性和规划,以及对面向对象核心原则的理解.如果你不愿意花时间学习和理解这些原则......那么,或许OOP编程不适合你.
除此之外,某些类型的问题也适用于其他编程风格.例如,变换处理对于编程的功能样式是非常可取的- 其中计算结果并将其传递到连续的变换步骤以产生最终结果.您必须在域中搜索或查询某些匹配信息的问题适用于查询语言(如SQL),您可以在其中以声明方式而非强制性描述您的意图.
能够识别您正在解决的问题类型在选择使用哪种语言或工具方面有很长的路要走.正确的工具可以使工作变得更容易......错误的工具可以使工作更难 - 或者不可能.
Uri*_*Uri 19
我不完全理解他的榜样.
然而,重要的是理解OOP是东西,可以自然地用它来模拟非常有效的,并且是其他的东西(例如,横切关注点或方面)非常无效是非常重要的.这是OOP的一个缺点.另一个原因是,由于动态调度,它经常会产生一些运行时成本.
此外,很容易滥用OOP来做无意义的抽象.火箭继承自身体就是一个例子.我的经验是,当其他行为(如聚合)更合适时,新手开发人员或者不信任并且不使用继承,或者他们过于渴望并且错误地使用它.随着时间的推移,对机制的经验和理解会有所改善
我不确定他的意思是"OOP模式不严格实现继承规则",因为OOP不是模式.一个潜在的问题是,人们可以编写一个可以违反Liskov替换原则的子类型,因此覆盖方法不会像被覆盖的方法那样"至少"表现.无法自动检查这一点,因此可以编写违反OOP原则的代码.
至于你的最后一个问题"我们可以在理想的面向对象设计中拔掉类层次结构吗?",我不确定你的意思.如果您要求在运行时更改层次结构,并使其从执行中的某个点不再存在子类型关系,那么是.对于某些语言,例如Smalltalk,它是可能的.有人会认为这是"更多OOP".在smalltalk中,类型支持的"方法"是在方法调用时根据当前层次结构和每个类的当前内容确定的.虽然我喜欢smalltalk,但这是一个我并不疯狂的功能,因为我更喜欢编译时检查,减少运行时间的惊喜.
jmu*_*llo 11
他的榜样毫无意义.火箭不会从身体继承.它"拥有"一个身体.这是遏制.所以有一点你会"删除"附加在火箭上的部分,因为它被抛弃了.
虽然我不完全理解给出的例子,因为它听起来像我的作文,我会给OOP一个缺点
OO很难测试
无法直接访问读/写类变量/属性 - 可能需要引入打破封装的getter和seeter.
继承可以更改子类中方法的行为
物体有状态.由于我们依赖于公共接口,因此很难生成这些状态.
具有loh内聚力的类可能难以测试,因为这可能意味着该类执行的操作超出了指定的范围.