Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/155.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java OOP的缺点?_Java_C++_Oop_Inheritance - Fatal编程技术网

Java OOP的缺点?

Java OOP的缺点?,java,c++,oop,inheritance,Java,C++,Oop,Inheritance,通常我不想知道OOPs的具体缺点,但当我在最近参加的一次采访中发生争执时,感觉有点奇怪。发布给我的问题是告诉我(OOP)的一个缺点。当时,我觉得OOP是继过程模型和函数模型之后最成熟的编程级别。所以我回答他说我根本看不到任何负面的东西 但面试官说很少,我请他列出一个,如果他不介意的话。他举了一个我不能很好理解的例子。他说OOP模式并没有严格执行继承规则,并引用了卫星/火箭的例子,在火箭发射过程中,身体部分会定期分解以减轻重量,他说继承不支持这一点 他的例子让我觉得很奇怪,原因是继承在这个例子中的

通常我不想知道OOPs的具体缺点,但当我在最近参加的一次采访中发生争执时,感觉有点奇怪。发布给我的问题是告诉我(OOP)的一个缺点。当时,我觉得OOP是继过程模型和函数模型之后最成熟的编程级别。所以我回答他说我根本看不到任何负面的东西

但面试官说很少,我请他列出一个,如果他不介意的话。他举了一个我不能很好理解的例子。他说OOP模式并没有严格执行继承规则,并引用了卫星/火箭的例子,在火箭发射过程中,身体部分会定期分解以减轻重量,他说继承不支持这一点

他的例子让我觉得很奇怪,原因是继承在这个例子中的应用

我知道他举的例子几乎毫无意义,但我有一个疑问-

我们可以取消类层次结构吗 (我有点自信 在Java中,这是不可能的)在理想情况下 面向对象设计


他的例子毫无意义。火箭不是从物体继承的。它“有”一个身体。这就是遏制。因此,在某一点上,当火箭被丢弃时,你会“删除”它所附的部件。

经典的做法是更喜欢组合而不是继承。继承是为了沿着系统变化的接缝捕获抽象

如果你没有很清楚地捕捉到这种抽象,那么是的,你的设计会受到奇怪的力量。但这是一个编程问题,在这个世界上,抽象并不完全适合您试图实现的目标。并不是说它们永远都是完美的

就因为你有一把锤子, 并不意味着一切都是钉子

我发现很多人经常混淆什么时候应用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";
    }
}