这可能不太适合Stackoverflow,但这是一个非常好的问题,应该加以解决。你偶然偶然发现了一个编程中的常见问题:大多数“OOP”程序实际上并不是面向对象的。
OOP的重点在于封装复杂性。艾伦凯最初从生物细胞的角度来设想它,细胞的所有机器都与外部世界隔绝,而且你只能通过输入和输出的信息与细胞相互作用。因此,一个对象封装了一个完整的系统,并且本身将由对象组成,并且可以与其他对象组合成更大的对象。而且一切都会与消息沟通,没有人能够窥视其他任何人。这就是面向对象编程的含义,大量的写作仍然受到这个想法的影响。但大多数自称为OOP的东西并不这样做(做的这样的工作现在通常被称为“Actor模型”,它可以是一种非常有效和可靠的编程方式,用Erlang等语言加以说明)。
今天大多数OOP系统认为一个对象是一个不太有趣的事情(至少在我看来):只是数据和方法的组合,可以作用于这些数据。行业内存在很大争论,这是否是一个特别有用的构造(相对于从方法中分离数据的功能范式,或纯粹集中于功能而非类的鸭子键入范例)。
但在实践中,我会说在大多数情况下,我们创建对象有两个原因:聚集数据并封装责任。这些是非常不同的东西,但在许多流行的语言中,它们都被视为“对象”。
在“丛块数据”的情况下,当你有一个逻辑上应该合在一起的数据集合时创建一个新对象。例如,Point是两个坐标的集合,这是一个非常好的“数据对象”。
关于“封装责任”,这指的是我们所说的“单一责任”原则。一个对象应该完全负责你可以命名的一个“事物”。例如,那个“东西”可能是“网络连接”,或者可能是“画这个窗口”。你有一个Connection类和一个Window类等等。真正的关键是命名。当你很容易命名它时,你知道你有一个好的课堂,并且它所做的一切似乎都是从你给它的名字开始的。当很难命名它时,你可能已经创建了错误的类。
类层次结构的关键教训叫做替代原则(由Barbara Liskov形式化)。如果你打算创建一个子类,它必须能够在任何地方使用它的超类可以被使用。所以Corgi IS-A狗,因为狗可以做的一切,Corgi可以做。但是,令人惊讶的是,一个Square是而不是是一个Rectangle。矩形可以创建两种长度。广场不能。 Square-Rectangle问题可能是导致继承错误的最常见原因。一个很好的教训是遗传是许多问题的错误工具。你应该喜欢结合多个对象而不是继承。所以在创建新类时,浅层次往往是最好的。如你所发现的,你所看到的大部分叫做“OOP”的只是包含在对象中的程序性编程。这对新人来说非常混乱。我们这些几十年来一直在做这件事的人很困惑。你只需要看看。
我通常遵循[单一责任原则](https://en.wikipedia.org/wiki/Single_responsibility_principle)如果课程开始有超过1个责任,我将其分成两部分(也可能是其中一个课程代表到另一个)。 – Augusto
这个问题会更适合StackExchange上的其他站点吗?我认为可能有一些具体的例子说明了什么是好的(实用的)面向对象,所以希望我们能避免看法。但它可能相当广泛。 – armadadrive