En el primer semestre, nos presentaron conceptos OOP como encapsulación, ocultación de datos, modularidad, herencia, etc. a través de Java y UML. (Java es mi primer lenguaje de programación)
Ninguno de esos son conceptos OOP. Todos existen fuera de OO, independientes de OO y muchos incluso fueron inventados antes de OO.
Entonces, si crees que de eso se trata OO, entonces tu conclusión es correcta: puedes hacer todo eso en lenguajes de procedimiento, porque no tienen nada que ver con OO .
Por ejemplo, uno de los documentos fundamentales sobre Modularidad es Sobre los criterios que se utilizarán en los sistemas de descomposición en módulos . No hay mención de OO allí. (Fue escrito en 1972, para entonces OO todavía era un nicho oscuro, a pesar de tener ya más de una década).
Si bien la abstracción de datos es importante en OO, es más una consecuencia de la característica principal de OO (Mensajería) que una característica definitoria. Además, es muy importante recordar que existen diferentes tipos de abstracción de datos. Los dos tipos más comunes de abstracción de datos que se usan actualmente (si ignoramos "ninguna abstracción", que probablemente todavía se usa más que las otras dos combinadas), son los tipos de datos abstractos y los objetos . Entonces, con solo decir "Ocultación de información", "Encapsulación" y "Abstracción de datos", no ha dicho nada sobre OO, ya que OO es solo una forma de abstracción de datos, y las dos son de hecho fundamentalmente diferentes:
- Con los tipos de datos abstractos, el mecanismo para la abstracción es el sistema de tipos ; Es el sistema de tipos que oculta la implementación. (El sistema de tipos no tiene por qué ser necesariamente estático). Con los objetos, la implementación se oculta detrás de una interfaz de procedimiento , que no requiere tipos. (Por ejemplo, se puede implementar con cierres, como se hace en ECMAScript).
- Con los tipos de datos abstractos, las instancias de diferentes ADT se encapsulan entre sí, pero las instancias del mismo ADT pueden inspeccionar y acceder a la representación y la implementación privada de cada uno. Los objetos siempre están encapsulados de todo . Solo el objeto en sí puede inspeccionar su propia representación y acceder a su propia implementación privada. Ningún otro objeto , ni siquiera otros objetos del mismo tipo, otras instancias de la misma clase, otros objetos que tengan el mismo prototipo, clones del objeto, o lo que sea que pueda hacer eso. Ninguno .
Lo que esto significa, por cierto, es que en Java, las clases no están orientadas a objetos. Dos instancias de la misma clase pueden acceder mutuamente a la representación y la implementación privada. Por lo tanto, las instancias de clases no son objetos, de hecho son instancias ADT. Java interface
s, sin embargo, no proporcionan la abstracción de datos orientada a objetos. En otras palabras: solo las instancias de interfaces son objetos en Java, las instancias de clases no lo son.
Básicamente, para los tipos, solo puede usar interfaces. Esto significa tipos de parámetros de métodos y constructores, tipos de métodos de retorno, tipos de campos de instancia, campos estáticos y campos locales, el argumento para un instanceof
operador o un operador de conversión, y los argumentos de tipo para un constructor de tipo genérico siempre deben ser interfaces. Una clase solo se puede usar directamente después del new
operador, en ningún otro lugar.
Por ejemplo, para modularidad, podemos dividir el programa en muchos programas pequeños que realizan tareas bien definidas cuyo código está contenido en archivos separados. Estos programas interactuarían entre sí a través de sus entradas y salidas bien definidas. Los archivos pueden estar protegidos (¿cifrados?) Para lograr la encapsulación. Para la reutilización del código, podemos llamar a esos archivos siempre que sean necesarios en nuevos programas. ¿Esto no captura todo lo que es OOP o me estoy perdiendo algo muy obvio?
Lo que describe es OO.
De hecho, esa es una buena manera de pensar en OO. De hecho, eso es exactamente lo que los inventores originales de OO tenían en mente. (Alan Kay fue un paso más allá: imaginó muchas pequeñas computadoras que se enviaban mensajes entre sí a través de la red). Lo que llama "programa" generalmente se llama "objeto" y, en lugar de "llamar", generalmente decimos "envíe un mensaje ".
La orientación a objetos se trata de mensajería (también conocido como despacho dinámico ). El término "Orientado a objetos" fue acuñado por el Dr. Alan Kay, el diseñador principal de Smalltalk, y lo define así :
OOP para mí significa solo mensajes, retención y protección local y ocultación del proceso estatal, y un enlace tardío extremo de todas las cosas.
Analicemos eso:
- mensajería ("envío de método virtual", si no está familiarizado con Smalltalk)
- proceso de estado debe ser
- retenido localmente
- protegido
- oculto
- atascamiento extremo de todas las cosas
En lo que respecta a la implementación, la mensajería es una llamada a un procedimiento con retraso, y si las llamadas a un procedimiento tienen un retraso, entonces no puede saber en tiempo de diseño a qué llamará, por lo que no puede hacer ninguna suposición 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.
Por lo tanto, hay dos formas de ver la definición de Alan Kay: si la mira por sí sola, puede observar que la mensajería es básicamente una llamada a un procedimiento vinculado de forma tardía y la vinculación tardía implica la encapsulación, por lo que podemos concluir que # 1 y # 2 son en realidad redundantes, y OO tiene que ver con la unión tardía.
Sin embargo, más tarde aclaró que lo importante es la mensajería, por lo que podemos verlo desde un ángulo diferente: la mensajería está retrasada. Ahora, si la mensajería fuera lo único posible, entonces el # 3 sería trivialmente cierto: si solo hay una cosa, y esa cosa está vinculada tarde, entonces todas las cosas están vinculadas tarde. Y una vez más, la encapsulación se deriva de la mensajería.
También se hacen puntos similares en On Understanding Data Abstraction, revisado por William R. Cook y también 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 pueden identificarse estáticamente, y no hay forma en general de [saber] exactamente qué operación se ejecutará en respuesta a una solicitud dada, 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.
Benjamin Pierce en Tipos y lenguajes de programación argumenta que la característica definitoria de la Orientación a objetos es la recursión abierta .
Entonces: según Alan Kay, OO tiene que ver con la mensajería. Según William Cook, OO tiene que ver con el envío de métodos dinámicos (que es realmente lo mismo). Según Benjamin Pierce, OO se trata de Open Recursion, lo que básicamente significa que las autorreferencias se resuelven dinámicamente (o al menos esa es una forma de pensar) o, en otras palabras, mensajes.
Como puede ver, la persona que acuñó el término "OO" tiene una visión bastante metafísica de los objetos, Cook tiene una visión bastante pragmática y Pierce una visión matemática muy rigurosa. Pero lo importante es: ¡el filósofo, el pragmático y el teórico están de acuerdo! La mensajería es el único pilar de OO. Período.
¡Tenga en cuenta que aquí no se menciona la herencia! La herencia no es esencial para OO. En general, la mayoría de los lenguajes OO tienen alguna forma de reutilización de implementación, pero eso no necesariamente tiene que ser herencia. También podría ser alguna forma de delegación, por ejemplo. De hecho, 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 lenguajes 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).