tl; dr: Puedes tener herencia sin OO, puedes tener encapsulación sin OO, puedes tener polimorfismo sin OO, incluso puedes tener los tres a la vez sin OO. Por otro lado, puede tener OO sin herencia. Además, hay diferentes tipos de encapsulación (orientada a ADT y OO), aunque no toda la encapsulación es OO.
Versión larga:
El término "Programación orientada a objetos" fue inventado por Alan Kay, por lo que puede decidir qué significa. Y lo define así :
OOP para mí significa solo mensajes, retención local y protección y ocultación del proceso estatal, y un enlace tardío extremo de todas las cosas.
En cuanto a la implementación, la mensajería es una llamada a procedimiento con retraso, y si las llamadas a procedimiento tienen retraso, entonces no puede saber en el momento del diseño qué llamará, por lo que no puede hacer suposiciones sobre la representación concreta del estado. Entonces, realmente se trata de mensajes, el enlace tardío es una implementación de mensajes y la encapsulación es una consecuencia de ello.
Más tarde aclaró que " La gran idea es 'enviar mensajes' ", y lamenta haberlo llamado "orientado a objetos" en lugar de "orientado a mensajes", porque el término "orientado a objetos" pone el foco en lo que no es importante (objetos ) y distrae de lo que es realmente importante (mensajes):
Solo un suave recordatorio de que me tomé algunas molestias en el último OOPSLA para tratar de recordarles a todos que Smalltalk no solo NO es su sintaxis o la biblioteca de clases, ni siquiera se trata de clases. Lamento haber acuñado hace mucho tiempo el término "objetos" para este tema porque hace que muchas personas se centren en la idea menor.
La gran idea es la "mensajería", de eso se trata el núcleo de Smalltalk / Squeak (y es algo que nunca se completó en nuestra fase Xerox PARC). Los japoneses tienen una pequeña palabra - ma - para "lo que está en el medio" - tal vez el equivalente en inglés más cercano es "intersticial". La clave para crear sistemas excelentes y que se puedan desarrollar es mucho más para diseñar cómo se comunican sus módulos en lugar de cuáles deberían ser sus propiedades y comportamientos internos. Piense en Internet: para vivir, (a) tiene que permitir muchos tipos diferentes de ideas y realizaciones que están más allá de cualquier estándar único y (b) para permitir diversos grados de interoperabilidad segura entre estas ideas.
(Por supuesto, hoy en día, la mayoría de las personas ni siquiera se enfocan en objetos sino en clases, lo cual es aún más incorrecto).
La mensajería es fundamental para OO, tanto como metáfora como mecanismo.
Si le envía un mensaje a alguien, no sabe qué hace con él. Lo único que puedes observar es su respuesta. No sabe si procesaron el mensaje ellos mismos (es decir, si el objeto tiene un método), si enviaron el mensaje a otra persona (delegación / representación), incluso si lo entendieron. De eso se trata la encapsulación, de eso se trata OO. Ni siquiera puede distinguir un proxy del real, siempre que responda como espera que lo haga.
Un término más "moderno" para "mensajería" es "despacho de método dinámico" o "llamada de método virtual", pero eso pierde la metáfora y se enfoca en el mecanismo.
También se hacen puntos similares en On Understanding Data Abstraction, revisado por William R. Cook y también en su Propuesta de definiciones modernas y simplificadas de "objeto" y "orientado a objetos" .
El despacho dinámico de operaciones es la característica esencial de los objetos. Significa que la operación a invocar es una propiedad dinámica del objeto en sí. Las operaciones no se pueden identificar de forma estática y, en general, no hay forma de saber exactamente qué operación se ejecutará en respuesta a una solicitud determinada, excepto ejecutándola. Esto es exactamente lo mismo que con las funciones de primera clase, que siempre se envían dinámicamente.
¡En Smalltalk-72, ni siquiera había ningún objeto! Había sólo flujos de mensajes que quedó analizando, reescrito y redireccionados. Primero llegaron los métodos (formas estándar de analizar y redirigir las secuencias de mensajes), luego vinieron los objetos (agrupaciones de métodos que comparten algún estado privado). La herencia llegó mucho más tarde, y las clases solo se introdujeron como una forma de apoyar la herencia. Si el grupo de investigación de Kay ya hubiera conocido los prototipos, probablemente nunca habrían introducido clases en primer lugar.
Todo programador debe leer Sobre la comprensión de la abstracción de datos, Revisited . Explica en detalle cuál es exactamente la diferencia entre Objetos y Tipos de datos abstractos. Da ejemplos usando Java, y eso es extremadamente relevante para esta pregunta, porque tanto en los ejemplos ADT como en los ejemplos Object usa herencia, encapsulación y polimorfismo, ¡pero solo uno de los ejemplos está orientado a objetos! En otras palabras: puede tener herencia, encapsulación y polimorfismo, incluso puede tener los tres a la vez y aún no tener OO.
Por otro lado, puede tener OO sin herencia. Como indiqué anteriormente: las versiones originales de Smalltalk (el lenguaje diseñado por Alan Kay, el inventor del término "Programación Orientada a Objetos") no tenían herencia.
Por último, pero no menos importante, el Tratado de Orlando analiza la delegación como una alternativa a la herencia y cómo las diferentes formas de delegación y herencia conducen a diferentes puntos de diseño dentro del espacio de diseño de los lenguajes orientados a objetos. (Tenga en cuenta que incluso en los idiomas que admiten la herencia, como Java, a las personas se les enseña a evitarlo, lo que nuevamente indica que no es necesario para OO)