¿Por qué la herencia, la encapsulación y el polimorfismo no son los pilares de la POO? [cerrado]

16

Un día fui a un chat de Stack Overflow y vi una frase que decía que la herencia, el encapsulado y el polimorfismo son los pilares de la POO (en el sentido de que son fundamentales, una suela de construcción).

Además, hay una pregunta similar, que me han preguntado muy a menudo en los exámenes universitarios y las entrevistas de trabajo, y la respuesta correcta siempre fue la declaración pronunciada en el título de la pregunta ("Sí, la herencia, la encapsulación y el polimorfismo son los pilares de la OOP )

Pero en el chat de Stack Overflow me ridiculizaron severamente, los participantes no estuvieron de acuerdo con tal declaración. Entonces, ¿qué tiene de malo esta afirmación?

¿Los programadores parecen estar entrenados en diferentes cosas en las universidades post-soviéticas y de los Estados Unidos?

¿La herencia, la encapsulación y el polimorfismo no son considerados los pilares de la POO por los programadores de EE. UU.

PaulD
fuente
77
Tu pregunta no tiene contexto; no sabemos qué pensaban las personas en el chat SO, ni a qué respondían. ¿Tal vez pueda vincular la conversación en la sala de chat para que podamos verla? Dicho esto, creo que esto se resuelve mejor en la sala de chat, en lugar de aquí.
Robert Harvey
1
@Robert, hace demasiado tiempo. Dudo si incluso puedo encontrar el enlace a la conversación. Pero estoy de acuerdo en que el contexto es importante. No es para culpar a alguien, o para presentarme como una víctima inocente de una agresión de chat, solo quiero saber la verdad.
PaulD
55
El salón. ¿Te pusiste primero tu traje a prueba de fuego?
Robert Harvey
1
El único significado que puedo dar a la oración es "puedes tener OOP sin ninguno de ellos" (es cierto, pero no tiene sentido al menos para encapsulación) o "puedes usarlos también fuera de OOP", o algo así.
SJuan76
2
Imo OO tiene un solo pilar y es: "Estado". Una vez que tu cerebro piensa en estado, obtienes OO.
Pieter B

Respuestas:

40

¿La herencia, la encapsulación y el polimorfismo no son considerados los pilares de la POO por los programadores de EE. UU.

Muchos programadores los consideran pilares, y muchas universidades enseñan OO de esa manera.

Desafortunadamente, también es una vista miope.

  • La herencia es solo un mecanismo utilizado para implementar OOP y se puede abusar de ella para no hacerla.
  • La encapsulación es un concepto, útil para la programación de todo tipo, OOP y no.
  • El polimorfismo es un ... rasgo (?) Para describir cómo se comporta la computación. Hay muchas formas de lograr el polimorfismo, no todas las cuales son OO específicas.

OOP tiene muy pocos fundamentos, ya que en realidad es muy conceptual: "Enfoque el diseño de su programa pensando en las cosas como objetos: paquetes cohesivos de datos y funcionalidad".

Y aunque el diseño moderno del programa tiene una visión pobre de hacer las cosas de una manera "puramente OO", la mayoría de los programadores expertos estarán de acuerdo en que los principios SÓLIDOS (o algún subconjunto) son mejores candidatos para los "pilares de la Programación Orientada a Objetos" (aunque aplicar bien a no OOP). Estos no funcionan con estos términos en absoluto. En su lugar, utilizan los conceptos de entidades de software (de las cuales, los objetos son uno), interfaces (de las cuales, C # / Java / etc. interfacees uno), abstracción y subtipado (de los cuales, la herencia es una forma).

Telastyn
fuente
10
Respuesta decente a una pregunta esencialmente sin respuesta.
Robert Harvey
3
¿Existe POO?
Tulains Córdova
55
Yo diría que solo la encapsulación es un "pilar" de la POO. La mayor diferencia entre OOP y la programación estructural es la idea de que los objetos contienen código y datos, no solo datos (por ejemplo, una estructura C clásica). Los otros dos conceptos se usan principalmente en lenguajes OO, pero no están restringidos a OO ni son requeridos por él.
3
@Snowman Encapsulation tampoco está restringido a OOP. Las personas implementan tipos de datos abstractos en C y lenguajes funcionales todo el tiempo.
Doval
2
Y @ JörgWMittag tuvo una buena respuesta con respecto a la mensajería. La idea de la mensajería necesariamente requiere encapsulación. Los mensajes generalmente se pasan a una función o método en un objeto, que luego actúa en el estado que está encapsulado en él. Eso no quiere decir que los lenguajes que no son OO no pueden tener mensajes o encapsulación también, solo que estas son ideas fundamentales de OOP.
23

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)

Jörg W Mittag
fuente
Puede tener "herencia", "polimorfismo" y "herencia" ... creo que hay un error tipográfico en alguna parte :)
slebetman
1
Esta respuesta me hace desear que también podamos 'responder' a las respuestas preferidas
Chan-Ho Suh
La definición de Alan Kay está desactualizada. OO necesita herencia, y si puede hacer tanto el enlace en tiempo de ejecución como el de compilación como en C ++, también obtendrá un rendimiento similar al de C.
Erik Alapää 01 de
No, su definición es la correcta. No necesitas herencia para ser OO. Los lenguajes prototipo no usan herencia como C ++ y siguen siendo OO. La herencia solo se usa para implementar la reutilización de código, ni siquiera es la mejor manera, hay muchos idiomas mejores que tienen mixins, por ejemplo. Tampoco tiene nada que ver con el enlace, ya que puede tener un despacho dinámico, ni siquiera en C ++ cuando puede usar métodos virtuales. El rendimiento no tiene nada que ver con nada de eso, son conceptos de alto nivel, no tienen rendimiento. De hecho, podría implementar el paso de mensajes en C y ser OO
Luiz Felipe