Mi madre hizo su tesis universitaria en Fortran y ahora (más de una década después) necesita aprender c ++ para simulaciones de fluidos. Es capaz de comprender toda la programación de procedimientos, pero no importa cuánto intente explicarle los objetos, no se pega. (Trabajo mucho con Java, por lo que sé cómo funcionan los objetos) Creo que podría estar explicándolo de manera demasiado importante, por lo que no tiene sentido para alguien que nunca trabajó con ellos y creció en la era de la programación puramente procesal.
¿Hay alguna manera simple de explicárselo que la ayude a entender?
object-oriented
fortran
Eric Pauley
fuente
fuente
Respuestas:
Respuesta corta: no.
Respuesta larga: no hay una "forma simple" porque la POO está lejos de ser simple. La programación de procedimientos tiene que ver con "variables" y "if then goto". Todo lo demás es azúcar sintáctica, pero esas cuatro cosas son de lo que se trata la programación procesal. Una vez que los consigas, nada puede detenerte.
OOP es una forma de organizar variables y piezas de código. ¿Cuántos patrones hay para definir OOP? 25? 30? Incluso los maestros que aprendieron OOP de diferentes idiomas y orígenes no están de acuerdo con su propia definición, entonces ... ¿cómo puede ser simple?
No sé cómo llegaste a eso, pero como tu madre tiene una experiencia similar a la mía, puedo decirte cómo llegué a eso.
Estaba programando en C en un proyecto muy grande. Era 1988. Muchos programadores organizaron módulos y bibliotecas, con la dificultad de evitar interferencias en otros trabajos y mantener una buena segregación de funciones.
Llegamos a una "solución" que consistía en poner todos los datos globales interrelacionados en estructuras, colocando en esa estructura algunos punteros de función donde se requerían devoluciones de llamada. Así generalizamos lo que llamamos
io_mask
(tipo de cuadros de diálogo de modo textual) ygraphic_manager
etc. etc.En 1996 fue muy fácil descubrir que esas estructuras se llamaban "clases" y que los punteros de funciones se reemplazaban por funciones miembro y funciones virtuales, o con enlaces a otros objetos (llamados comportamientos) por otros programadores que renovaron ese antiguo proyecto.
Comencé a comprender la POO cuando comencé a sentir la necesidad de ello: segregación, polimorfismo y comportamientos definidos en tiempo de ejecución.
Hoy trabajo con OOP, pero no lo considero una doctrina para servir: solo un "idioma común" (conjunto de ...) que nos permite hablar juntos sin la necesidad de proporcionar largas explicaciones y descripciones todo el tiempo . De hecho, es más una "convención" que otra cosa. Después de todo, todo lo que hace OOP es -toda- "si luego ir a": simplemente lo hace "multicapa". De ahí la abstracción y modismos sobre modismos.
Ingnóralos. Hasta que no sienta la necesidad de ellos, ni siquiera intente explicar: los sentirá como una forma complicada de hacer cosas simples. Y ella tiene razón ... hasta que lo que hace es, de hecho, simple.
Nadie pensará "organizar un escritorio" si solo hay cuatro cosas encima. Tiene sentido cuando las cosas de arriba comienzan a interferir entre sí. Ese es el momento para que entre OOP.
No necesita OOP para trabajar con C ++. Toda la biblioteca estándar de C ++ no está diseñada en términos de OOP (aunque puede cooperar con ella), y C ++ no es Java.
En mi experiencia, los peores maestros y programadores de C ++ son los que provienen de Java, y enseñan todos sus prejuicios acerca de que todo no es OOP, desnaturalizando un lenguaje como C ++ que no es (solo) para OOP.
Permítanme sugerir un buen libro para aquellos que quieren acercarse a C ++: C ++ acelerado : lo llevará a los modismos de C ++ sin pretender seguir una doctrina predefinida.
fuente
Un viejo amigo afirmó que tenía la definición más corta que conocía de la programación OO, y descubrí que funciona para algunas personas (y no para otras):
La programación orientada a objetos son datos con una opinión. No mueves la silla, le pides a la silla que se mueva sola. No ordena la lista, le pide que se ordene a sí misma (quizás con una pista). Etc.
La idea es hacer que la persona piense de manera diferente sobre cómo se hacen las cosas dentro de su programa.
fuente
Dile que piense en objetos como objetos en el mundo real. Por ejemplo, el mundo entero puede ser una mezcla de programación orientada a objetos (en C ++) con algún tipo de programación funcional (probablemente realizada en el lenguaje de Dios, Lisp).
Tome un objeto, por ejemplo, el cortacésped, tiene ciertos atributos y puede hacer algo. (objeto y clase)
Luego cuéntele sobre un mejor cortacésped, que es una extensión del cortacésped que ya tiene. Dile que es mejor pero que aún se basa en el mismo mecanismo (herencia).
Entonces cuéntale sobre ti. Dile que a veces puedes convertirte en un experto en cortar el césped, pero en realidad eres un programador y lo haces para vivir. Es como si actuaras como dos entidades diferentes al mismo tiempo. Esto es polimorfismo.
Cuando reciba esto, cuéntele cómo implementar estas cosas en el lenguaje que tiene que aprender (C ++).
Luego dígale que si tiene que escribir una simulación de este mundo en el mundo de las computadoras, tendrá que aprender a hacerlo.
Cuando sabe cómo convertir sus pensamientos del mundo real en código de programa. ella habría aprendido a programar en lenguaje de programación orientado a objetos.
fuente
He pasado de ensamblador y COBOL a Ruby.
Lo que me ayudó inicialmente fue ignorar el concepto de clases que crean instancias.
Solo comienza con el código. Tener una clase pero solo tener métodos a nivel de clase. Dentro de los métodos, hay muchas cosas sobre parámetros, variables, condicionales, matrices, cadenas, booleanos, etc. Estas cosas deberían ser familiares.
Entonces, en este punto, se puede ver que la clase solo sirve como un lugar para colocar todos sus métodos relacionados. Llámelo un contenedor o una biblioteca será más familiar para ella.
Obviamente, el código debe segmentarse para que sea manejable, de modo que tenga uno de estos en cada área. Por ejemplo, para administrar un conjunto de programas de utilidad en una PC, es posible que tenga una clase de calculadora donde podría colocar todo el código de una calculadora en un solo lugar. Si solo tiene 1 calculadora en su PC, los métodos de nivel de clase son suficientes.
Eso es un comienzo.
ok ahora considera el hecho de que deseas abrir varias calculadoras y cambiar la apariencia de cada una y dónde está en la pantalla. Entonces, ahora no puede simplemente tener un método de calculadora como 'screen_location' porque tiene varios de ellos y cada instancia tiene su propia ubicación ... cada instancia ... ok, entonces necesitamos instancias.
Nota: mis términos son de ruby no de c ++, por lo que es posible que deba traducir.
fuente
Lo explicaría en dos pasos, o tal vez cuatro, dependiendo de cuánto te guste dividir tus conceptos.
Paso 1: preséntale estructuras. Es un paso bastante pequeño de los tipos de datos de Fortran a las estructuras. Paso 1a: asegúrese de que no tenga en cuenta la asignación dinámica de memoria y los punteros.
Paso 2: agregue procedimientos asociados solo con esas estructuras. Paso 2a: agregue herencia basada en la construcción de estructuras más grandes que "envuelven" estructuras más pequeñas.
Para un programador de Fortran, el factor "wow" será que el compilador tiene mucho que hacer un seguimiento. Sip. Para eso están los compiladores ...
fuente
Si hizo su tesis hace una década, probablemente usó Fortan 90 o 95, en cuyo caso lo que se debe hablar es en relación con los tipos de datos derivados. Si fue hace bastante tiempo que usó Fortran 77, entonces preséntele los tipos de datos derivados en Fortran 90 y luego hable sobre eso ...
No entraría en el polimorfismo y la herencia, hasta después de que ella haya comprendido la encapsulación, ya que pueden verse como casos especiales y extensiones de encapsulación. Probablemente la iniciaría en un lenguaje que permita funciones gratuitas o clases estáticas.
fuente
Una vez que comprenda las estructuras, creo que el siguiente punto clave será reconocer que la programación orientada a objetos sirve como un medio para limitar el conjunto de métodos a los que se puede pasar una cosa, al conjunto de métodos que realmente podrían aplicarse a ese cosa.
En la programación no orientada a objetos, si uno usa tipos de datos separados para un árbol y una lista enlazada, uno tendría que usar diferentes métodos para agregar un nodo a cada uno. Lenguajes no orientados a objetos serían generalmente graznido si se trató de nombrar a los dos métodos
AddItem
, ya que cualquier nombre que se da sólo puede referirse a un método, lo que conduce uno para crear nombres de métodos comoAddTreeItem
,AddLinkedListItem
,RemoveTreeItem
, etc. Este enfoque funciona, pero es un poco feo. Conceptualmente, los métodosAddTreeItem
yRemoveTreeItem
parecen estar juntos, pero los nombres no se ordenan de esa manera. Se podría volver a escribir los nombres comoTreeAddItem
,TreeRemoveItem
,LinkedListAddItem
, etc. pero eso pondría mucho "ruido redundante" al comienzo de cada invocación de método. La gran mayoría de las llamadas a métodos en un programa típico tendrá tres datos esenciales: (1) qué sección del código fuente contiene el método; (2) cuál de los métodos en la sección se está utilizando; (3) ¿sobre qué datos se está actuando? En muchos casos, el tipo de datos sobre los que se actúa será suficiente para identificar a qué sección de código pertenece el método, por lo que la parte (1) de lo anterior es redundante. Es más fácil identificar visualmente el material al comienzo de una declaración que el material en cualquier otro lugar, por lo que un estilo de codificación / denominaciónTreeAddItem(myTree, whatever)
termina poniendo la información menos útil en el primer lugar.Por el contrario, usando la programación orientada a objetos, uno efectivamente nombraría métodos como
Tree.AddItem
, etc. y una declaración comomyTree.AddItem(whatever)
haría que un compilador dijera, esencialmente, "Hmm ...myTree
es de tipoTree
, por lo que este código debería invocarTree.AddItem()
. No es necesario especifique elTree.
al llamarAddItem
ya que el compilador conoce el tipo demyTree
. Conceptualmente, una instrucción comomyTree.AddItem(whatever)
es equivalente aTree.AddItem(myTree, whatever)
, y algunos lenguajes orientados a objetos pueden permitir ambas formas como equivalentes; de hecho, la mayoría de los idiomas omiten el primer parámetro de la especificación de la función y en su lugar tienen métodos que se definen en una clase comoTree
implícitamente toman un parámetro de tipoTree
, y asignarle un nombre comothis
,self
oMe
.Los lenguajes de programación orientados a objetos a menudo incluyen una variedad de características adicionales como herencia, funciones virtuales, etc., que son muy útiles en muchas aplicaciones, pero incluso sin esas características, la capacidad de agrupar funciones de acuerdo con las cosas sobre las que operan es muy útil.
fuente
La programación orientada a objetos, en el sentido orientado a clases relevante aquí, se trata de acoplar una representación de datos con el código que la manipula. Tiene sentido si las siguientes cosas tienen sentido:
Acoplamiento: definición de una operación junto con la representación de datos en la que trabaja
Enlace tardío: elegir una combinación de representación de datos y comportamiento en tiempo de ejecución
Encapsulación: asegurando que los datos son válidos por construcción y no serán invalidados más tarde
Eso es todo. Al igual que cualquier tecnología, en esencia es simplemente una conveniencia, de la cual se han seguido muchos desarrollos más tarde. Una vez que comprenda los conceptos básicos, el resto sigue en el tiempo.
fuente
Sugeriría descargar BlueJ, jugar con él durante 20 minutos y luego hacer que juegue con él durante 20 minutos.
La forma en que visualiza las clases, las interfaces y la herencia es tan obvia e intuitiva que realmente le brinda una comprensión instantánea a medida que implementa algo, cualquier cosa.
Incluso te muestra directamente la diferencia entre una clase y un objeto
No brindará una visión profunda de los patrones de diseño OO, pero brindará una fantástica descripción general de los conceptos.
fuente
Me gustaría agregar mi contribución como recordatorio de la distinción entre paradigmas de programación y lenguajes de programación que implementan estos paradigmas.
Entonces, en mi opinión, la mejor manera de explicar la orientación de objetos con C ++ a un usuario F77, sería proceder de manera gradual:
Primero, presente al usuario el concepto de orientación a objetos en un entorno familiar mostrándole cómo desarrollar estructuras similares a objetos en Fortran 77; por ejemplo, eche un vistazo a documentos como B. Patton "Fortran 77 orientado a objetos (un profesional ver) "SIGPLAN Fortran Forum 12, 2 (1993), pp. 23-24, y referencias en el mismo.
Luego, establezca una correspondencia entre esas estructuras y las clases y métodos de C ++.
Finalmente, analice las características adicionales que C ++ puede proporcionar para facilitar la programación OO.
fuente
Cuando estaba migrando por primera vez a un lenguaje orientado a objetos desde mi entrenamiento inicial en Pascal, el '.' El problema fue el mayor obstáculo para mí también. Me llevó años superarlo.
En realidad, no es intuitivo que una variable pertenezca a otra variable, especialmente cuando estás acostumbrado a pensar en ellas como punteros. El obstáculo para mí fue:
El momento aha para mí fue cuando me di cuenta de que el puntero de nivel superior era básicamente solo un espacio de nombres.
Sugeriría que escribiera un montón de código que requiera que ella asigne un espacio de nombres a sus funciones, idealmente sin usar la notación de puntos para comenzar. Luego haga que intente reescribirlo usando la notación de puntos.
Hacer ese ejercicio debería ayudarla a superar el "¿Qué brujería es esta?" obstáculo.
fuente
Una idea clave que me ha ayudado a explicar antes es el hecho de que puede tener varias instancias de una clase. Trate de explicar eso en términos de "dibujos" o "moldes" y "copias" y vea si lleva a alguna parte.
fuente