Java OOP的缺点?
通常我不想知道OOPs的具体缺点,但当我在最近参加的一次采访中发生争执时,感觉有点奇怪。发布给我的问题是告诉我(OOP)的一个缺点。当时,我觉得OOP是继过程模型和函数模型之后最成熟的编程级别。所以我回答他说我根本看不到任何负面的东西 但面试官说很少,我请他列出一个,如果他不介意的话。他举了一个我不能很好理解的例子。他说OOP模式并没有严格执行继承规则,并引用了卫星/火箭的例子,在火箭发射过程中,身体部分会定期分解以减轻重量,他说继承不支持这一点 他的例子让我觉得很奇怪,原因是继承在这个例子中的应用 我知道他举的例子几乎毫无意义,但我有一个疑问- 我们可以取消类层次结构吗 (我有点自信 在Java中,这是不可能的)在理想情况下 面向对象设计Java OOP的缺点?,java,c++,oop,inheritance,Java,C++,Oop,Inheritance,通常我不想知道OOPs的具体缺点,但当我在最近参加的一次采访中发生争执时,感觉有点奇怪。发布给我的问题是告诉我(OOP)的一个缺点。当时,我觉得OOP是继过程模型和函数模型之后最成熟的编程级别。所以我回答他说我根本看不到任何负面的东西 但面试官说很少,我请他列出一个,如果他不介意的话。他举了一个我不能很好理解的例子。他说OOP模式并没有严格执行继承规则,并引用了卫星/火箭的例子,在火箭发射过程中,身体部分会定期分解以减轻重量,他说继承不支持这一点 他的例子让我觉得很奇怪,原因是继承在这个例子中的
他的例子毫无意义。火箭不是从物体继承的。它“有”一个身体。这就是遏制。因此,在某一点上,当火箭被丢弃时,你会“删除”它所附的部件。经典的做法是更喜欢组合而不是继承。继承是为了沿着系统变化的接缝捕获抽象 如果你没有很清楚地捕捉到这种抽象,那么是的,你的设计会受到奇怪的力量。但这是一个编程问题,在这个世界上,抽象并不完全适合您试图实现的目标。并不是说它们永远都是完美的 就因为你有一把锤子, 并不意味着一切都是钉子 我发现很多人经常混淆什么时候应用OOP和什么时候使用OOP作为编程风格。你在面试问题中引用的例子似乎就是这种混淆的一个例子 我从经验中学到的一点是,虽然继承是表达设计中实体之间“是-是”关系的一个很好的范例,通常更倾向于组合而不是继承 但是让我们来看看面试官问题的关键:OOP什么时候是一个糟糕的范例选择 面向对象编程最适合大规模、多开发人员、多模块项目。对于“小型开发”——如脚本编写或转换处理,它可能需要大量开销,而不一定会增加价值。但即使在这些情况下,除非您编写的是一次性代码,否则我认为大型解决方案通常会从小型解决方案演变而来,因此尽早建立结构和分离关注点可以避免您以后的悲伤 最终,OOP编程还需要一定程度的设计严谨性和规划,以及对环境的理解如果你不愿意花时间学习和理解这些原则。。。那么,也许面向对象编程不适合您。 除此之外,某些类型的问题也适用于其他编程风格。例如,转换处理非常容易处理-其中计算结果并传递给后续转换步骤以生成最终结果。您必须搜索或查询某个域以获取某些匹配信息的问题(如SQL)通常以声明方式而非强制方式描述您的意图
能够识别您正在解决的问题类型,对于选择使用哪种语言或工具有很大帮助。正确的工具可以使工作更轻松。。。错的人可能会让事情变得更难,甚至不可能。我可以看出他想表达的意思。我认为争论基本上是围绕继承的缺点展开的——如果你不小心,或者如果你继承了太多次而无法继续扩展功能,那么你最终可能会得到一个臃肿的类,它有大量冗余的特性,缺乏内聚性
如果你认为火箭一旦在段中燃烧了燃料,那么该段就变成多余的,因此是自重。火箭可以抛弃这个片段,但我认为不可能排除您不想继承的类的部分(尽管如果我错了,请纠正我,因为这听起来很有用)。我不完全理解他的示例 然而,理解OOP对于可以自然建模的事物非常有效,对于其他事物(例如横切关注点或方面)非常无效,这一点很重要。这是OOP的一个缺点。另一个原因是,由于动态调度,它通常会产生一些运行时成本 此外,很容易滥用OOP来进行无意义的抽象。从实体继承火箭就是一个例子。我的经验是,新手开发人员要么不信任也不使用继承,要么他们过于渴望并错误地使用继承,而其他行为(如聚合)更合适。随着时间的推移,对该机制的经验和理解不断提高 我不确定他所说的“OOP模式不严格实现继承规则”是什么意思,因为OOP不是一种模式。一个潜在的问题是,可以编写一个子类型,该子类型可能违反Liskov的替换原则,因此重写方法的行为“至少”不像被重写的方法。没有办法自动检查这一点,因此有可能编写违反OOP原则的代码 至于你的最后一个问题“我们能在理想的面向对象设计中去掉类层次结构吗?”,我不确定你在这里的意思。如果您询问在运行时更改层次结构,并
public class SpaceShip {
private ISpaceShipState m_state = new SaturnFiveState();
public void setState(ISpaceShipState state) {
m_state = state;
}
public void jettison() {
m_state = m_state.transition();
}
public int getStageNumber() {
return m_stage.getStageNumber();
}
public int getNumberOfRocketMotors() {
return m_stage.getNumberOfRocketMotors();
}
public String getRocketMotorTypeName() {
return m_stage.getRocketMotorTypeName();
}
}
interface ISpaceShipState {
public ISpaceShipState transition();
public int getStageNumber();
public int getNumberOfRocketMotors();
public String getRocketMotorTypeName();
}
public class SaturnFiveState implements ISpaceShipState {
public ISpaceShipState transition() {
return new SaturnFiveSecondStageState();
}
public int getStageNumber() {
return 1;
}
public int getNumberOfRocketMotors() {
return 5;
}
public String getRocketMotorTypeName() {
return "F-1";
}
}
public class SaturnFiveSecondStageState implements ISpaceShipState {
public ISpaceShipState transition() {
return new SaturnFiveThirdStageState();
}
public int getStageNumber() {
return 2;
}
public int getNumberOfRocketMotors() {
return 5;
}
public String getRocketMotorTypeName() {
return "J-2";
}
}
public class SaturnFiveThirdStageState implements ISpaceShipState {
public ISpaceShipState transition() {
return new SaturnFiveCommandModuleState();
}
public int getStageNumber() {
return 3;
}
public int getNumberOfRocketMotors() {
return 1;
}
public String getRocketMotorTypeName() {
return "J-2";
}
}