oop - sirve - programacion orientada a objetos ejemplos
¿Por qué la afirmación de que c#personas no obtienen programación orientada a objetos?(frente a la clase) (14)
Esto llamó mi atención anoche.
En el último podcast ALT.NET Scott Bellware analiza cómo, a diferencia de Ruby, idiomas como c #, java et al. no están realmente orientados a objetos sino que optan por la frase "orientado a las clases". Hablan de esta distinción en términos muy vagos sin entrar en muchos detalles o discutir mucho sobre los pros y los contras.
¿Cuál es la diferencia real aquí y cuánto importa? ¿Qué son los otros idiomas que están "orientados a objetos"? Parecía bastante interesante, pero no quiero tener que aprender a Ruby solo para saber qué es lo que me falta.
Actualización : después de leer algunas de las respuestas a continuación, parece que las personas generalmente están de acuerdo en que la referencia es escribir patos. Lo que aún no estoy seguro de entender es la afirmación de que esto finalmente cambia todo eso. Especialmente si ya está haciendo el tdd correcto con acoplamiento flojo, bla, bla, bla. ¿Puede alguien mostrarme un ejemplo de algo maravilloso que podría hacer con ruby que no puedo hacer con c # y que ejemplifica este enfoque diferente?
OO a veces se define como orientado a mensajes . La idea es que una llamada a un método (o acceso a la propiedad) es realmente un mensaje enviado a otro objeto. La forma en que el objeto receptor maneja el mensaje está completamente encapsulado. A menudo, el mensaje corresponde a un método que luego se ejecuta, pero eso es solo un detalle de implementación. Por ejemplo, puede crear un controlador catch-all que se ejecuta independientemente del nombre del método en el mensaje.
El OO estático como en C # no tiene este tipo de encapsulación. Un masaje debe corresponder a un método o propiedad existente, de lo contrario, el compilador se quejará. Sin embargo, los lenguajes dinámicos como Smalltalk, Ruby o Python admiten OO "basado en mensajes".
Entonces, en este sentido, C # y otros lenguajes OO estáticos no son verdaderos OO, ya que carecen de una encapsulación "verdadera".
Eso fue un podcast abstracto de hecho!
Pero veo a lo que se dirigen: simplemente se deslumbraron con Ruby Sparkle. Ruby te permite hacer cosas que los programadores basados en C y Java ni siquiera pensarían + las combinaciones de esas cosas te permiten alcanzar posibilidades inimaginables. Agregando nuevos métodos a una clase de String incorporada porque te da la gana, pasando bloques de código sin nombre para que otros los ejecuten, mixins ... La gente convencional no está acostumbrada a que los objetos cambien demasiado lejos de la plantilla de la clase. Es un mundo completamente nuevo, seguro.
En cuanto a los chicos de C # que no son lo suficientemente buenos ... no lo tomes en serio. Solo tómalo como lo que dices cuando estás estupefacto por las palabras. Ruby le hace eso a la mayoría de la gente.
Si tuviera que recomendar un idioma para que la gente lo aprendiera en la década actual ... sería Ruby. Me alegro de haberlo hecho ... Aunque algunas personas pueden reclamar Python. Pero es como mi opinión ... ¡hombre! :RE
Haré una puñalada en esto.
Python y Ruby son de tipo pato. Para generar cualquier código que se pueda mantener en estos idiomas, prácticamente tiene que usar un desarrollo basado en pruebas. Como tal, es muy importante para un desarrollador insertar fácilmente dependencias en su código sin tener que crear un marco de soporte gigante.
El éxito de la inyección de dependencia depende de tener un modelo de objeto bastante bueno. Los dos son una especie de dos caras de la misma moneda. Si realmente entiende cómo usar OOP, entonces debería crear diseños por defecto donde las dependencias puedan ser fácilmente inyectadas.
Debido a que la inyección de dependencia es más fácil en los lenguajes de tipado dinámico, los desarrolladores de Ruby / Python sienten que su lenguaje comprende las lecciones de OO mucho mejor que otras contrapartes de tipo estático.
Hay tres pilares de OOP
- Encapsulación
- Herencia
- Polimorfismo
Si un lenguaje puede hacer esas tres cosas, es un lenguaje OOP.
Estoy bastante seguro de que el argumento del lenguaje X hace OOP mejor que el lenguaje A continuará para siempre.
Los comentarios de tipaje de pato aquí se atribuyen más al hecho de que Ruby y Python son más dinámicos que C #. Realmente no tiene nada que ver con su naturaleza OO.
Lo que (creo) que Bellware quiso decir con eso es que en Ruby, todo es un objeto. Incluso una clase. Una definición de clase es una instancia de un objeto. Como tal, puede agregar / cambiar / eliminar el comportamiento en el tiempo de ejecución.
Otro buen ejemplo es que NULL también es un objeto. En ruby, todo es LITERALMENTE un objeto. Tener un OO tan profundo en todo su ser permite algunas técnicas de meta-programación divertidas, como la eliminación de métodos.
Probablemente esto se deba a lo que estas personas ven que otros hacen en c # y java en lugar de c # y java que admiten OOP. La mayoría de los lenguajes pueden usarse en diferentes paradigmas de programación. Por ejemplo, puede escribir código de procedimiento en c # y esquema, y puede hacer programación funcional en java. Se trata más de lo que estás tratando de hacer y de lo que el lenguaje respalda.
Solo escuché los primeros 6-7 minutos del podcast que provocó tu pregunta. Si su intención es decir que C # no es un lenguaje puramente orientado a objetos, eso es realmente correcto. Todo en C # no es un objeto (al menos las primitivas no lo son, aunque el boxeo crea un objeto que contiene el mismo valor). En Ruby, todo es un objeto. Daren y Ben parecen haber cubierto todas las bases en su discusión sobre "pato-tipado", así que no lo repetiré.
Si esta diferencia (todo un objeto versus todo no es un objeto) es material / significativa es una pregunta que no puedo responder fácilmente porque no tengo suficiente profundidad en Ruby para compararla con C #. Aquellos de ustedes que conocen Smalltalk (no lo creo, aunque desearía haberlo hecho) probablemente hayan estado mirando el movimiento Ruby con algo de diversión ya que fue el primer lenguaje puro de OO hace 30 años.
No creo que esto sea específicamente sobre el tipado de patos. Por ejemplo, C # admite la tipificación limitada de patos, un ejemplo sería que puede utilizar foreach en cualquier clase que implemente MoveNext y Current.
El concepto de pato-tipado es compatible con lenguajes tipados estáticos como Java y C #, es básicamente una extensión de la reflexión.
Este es realmente el caso de la tipificación estática frente a la dinámica. Ambos son apropiados-OO, en la medida en que existe tal cosa. Fuera de la academia, realmente no vale la pena debatir.
El código de basura puede escribirse en cualquiera de los dos. Se puede escribir un gran código en cualquiera de los dos. No hay absolutamente nada funcional que un modelo pueda hacer que el otro no pueda.
La verdadera diferencia está en la naturaleza de la codificación hecha. Los tipos estáticos reducen la libertad, pero la ventaja es que todos saben a lo que se enfrentan. La oportunidad de cambiar instancias sobre la marcha es muy poderosa, pero el costo es que se hace difícil saber con qué se está saliendo.
Por ejemplo, para Java o C # intellisense es fácil: el IDE puede producir rápidamente una lista de posibilidades. Para Javascript o Ruby esto se vuelve mucho más difícil.
Para ciertas cosas, por ejemplo, producir una API con la que alguien más codificará, existe una ventaja real en el tipado estático. Para otros, por ejemplo, producir rápidamente prototipos, la ventaja es dinámica.
Vale la pena tener una comprensión de ambos en tu caja de herramientas de habilidades, pero no tan importante como entender el que ya usas en profundidad real.
¿Tal vez están aludiendo a la diferencia entre la tipificación de patos y las jerarquías de clase?
si camina como un pato y grazna como un pato, simplemente finge que es un pato y patealo.
En C #, Java etc. el compilador se preocupa mucho acerca de: ¿Se le permite hacer esta operación en ese objeto?
Orientado a objetos vs. Orientado a clases podría por lo tanto significar: ¿El lenguaje se preocupa por objetos o clases?
Por ejemplo: en Python, para implementar un objeto iterable, solo necesita suministrar un método __iter__()
que devuelve un objeto que tiene un método llamado next()
. Eso es todo: no hay implementación de interfaz (no existe tal cosa). Sin subclases Solo hablando como un pato / iterador.
EDITAR: Esta publicación fue actualizada mientras reescribí todo. Lo siento, nunca más volveré a hacer eso. El contenido original incluía consejos para aprender la mayor cantidad de idiomas posible y no preocuparse por lo que piensan o dicen los médicos sobre un idioma.
Actualización: Es la nueva ola ... que sugiere que todo lo que hemos estado haciendo hasta ahora es pasarse ... Parece que se está apuntalando bastante en podcasts y libros ... Tal vez esto es lo que escuchaste.
Hasta ahora nos hemos preocupado por las clases estáticas y no hemos desatado el poder del desarrollo orientado a objetos. Hemos estado haciendo ''dev basado en clase''. Las clases son plantillas fijas / estáticas para crear objetos. Todos los objetos de una clase son creados iguales.
Por ejemplo, para ilustrar sobre lo que he estado balbuceando ... permítanme tomar prestado un fragmento de código de Ruby del screencast de PragProg que acabo de tener el privilegio de ver. El "desarrollo basado en prototipos" desdibuja la línea entre los objetos y las clases ... no hay diferencia.
animal = Object.new # create a new instance of base Object
def animal.number_of_feet=(feet) # adding new methods to an Object instance. What?
@number_of_feet = feet
end
def animal.number_of_feet
@number_of_feet
end
cat = animal.clone #inherits ''number_of_feet'' behavior from animal
cat.number_of_feet = 4
felix = cat.clone #inherits state of ''4'' and behavior from cat
puts felix.number_of_feet # outputs 4
La idea es que es una forma más poderosa de heredar el estado y el comportamiento que la herencia basada en clases tradicionales. Le da más flexibilidad y control en ciertos escenarios "especiales" (que aún no he entendido). Esto permite cosas como Mix-ins (re usando comportamiento sin herencia de clase) ..
Al desafiar las primitivas básicas de cómo pensamos acerca de los problemas, ''POO verdadero'' es como ''la Matriz'' de alguna manera ... Sigues WTF en un ciclo. Como este ... donde la clase base de Container puede ser un Array o un Hash basado en qué lado de 0.5 es el número aleatorio generado.
class Container < (rand < 0.5 ? Array : Hash)
end
Ruby, javascript y la nueva brigada parecen ser los pioneros en esto. Todavía estoy afuera en este ... leyendo e intentando darle sentido a este nuevo fenómeno. Parece ser poderoso ... demasiado poderoso ... ¿Útil? Necesito que mis ojos se abran un poco más. Tiempos interesantes ... estos.
En un lenguaje orientado a objetos, los objetos se definen definiendo objetos en lugar de clases, aunque las clases pueden proporcionar algunas plantillas útiles para definiciones específicas de una determinada abstracción. En un lenguaje orientado a clases, como C # por ejemplo, los objetos deben estar definidos por clases, y estas plantillas generalmente se conservan y empaquetan y se vuelven inmutables antes del tiempo de ejecución. Esta restricción arbitraria de que los objetos deben definirse antes del tiempo de ejecución y que las definiciones de los objetos son inmutables no es un concepto orientado a objetos; está orientado a clases
IMO, realmente define excesivamente "orientado a objetos", pero a lo que se refieren es que Ruby, a diferencia de C #, C ++, Java, y otros, no hace uso de la definición de una clase - realmente solo trabajas directamente con objetos . Por el contrario, en C # por ejemplo, usted define las clases que luego debe crear una instancia en el objeto por medio de la nueva palabra clave. El punto clave es que debes declarar una clase en C # o describirla. Además, en Ruby, todo , incluso los números, por ejemplo, es un objeto. Por el contrario, C # todavía conserva el concepto de un tipo de objeto y un tipo de valor. De hecho, creo que ilustra el punto que hacen sobre C # y otros lenguajes similares: el tipo de objeto y el tipo de valor implican un sistema de tipo , lo que significa que tiene un sistema completo de tipos de descripción en lugar de simplemente trabajar con objetos.
Conceptualmente, creo que el diseño de OO es lo que proporciona la abstracción para usarlo en la complejidad de los sistemas de software actualmente. El lenguaje es un uso de herramienta para implementar un diseño OO; algunos lo hacen más natural que otros. Todavía diría que a partir de una definición más común y más amplia, C # y los demás siguen siendo lenguajes orientados a objetos.
Object Oriented es un concepto. Este concepto se basa en ciertas ideas. Los nombres técnicos de estas ideas (en realidad, más bien principios que evolucionaron a lo largo del tiempo y que no han estado allí desde la primera hora) ya se han mencionado anteriormente, no voy a repetirlos. Estoy explicando esto tan simple y no técnico como puedo.
La idea de la programación OO es que hay objetos. Los objetos son pequeñas entidades independientes. Estas entidades pueden tener información incrustada o no. Si tienen dicha información, solo la entidad puede acceder a ella o cambiarla. Las entidades se comunican entre sí enviando mensajes entre sí. Compare esto con los seres humanos. Los seres humanos son entidades independientes, que tienen datos internos almacenados en su cerebro e interactúan entre sí mediante la comunicación (por ejemplo, hablar entre ellos). Si necesita conocimiento del cerebro de alguien más, no puede acceder directamente a él, debe hacerle una pregunta y él puede responder eso, diciéndole lo que quería saber.
Y eso es básicamente eso. Esta es una idea real detrás de la programación OO. Al escribir estas entidades, define la comunicación entre ellas y las hace interactuar juntas para formar una aplicación. Este concepto no está ligado a ningún idioma. Es solo un concepto y si escribes tu código en C #, Java o Ruby, eso no es importante. Con un poco de trabajo adicional, este concepto se puede incluso hacer en C puro, a pesar de que es un lenguaje funcional pero ofrece todo lo que necesita para el concepto.
Diferentes idiomas han adoptado este concepto de programación OO y, por supuesto, los conceptos no siempre son iguales. Algunos idiomas permiten lo que otros idiomas prohíben, por ejemplo. Ahora uno de los conceptos que participan es el concepto de clases. Algunos idiomas tienen clases, otros no. Una clase es un plano de cómo se ve un objeto. Define el almacenamiento interno de datos de un objeto, define los mensajes que un objeto puede entender y si hay herencia (¡lo cual no es obligatorio para la programación OO!), Las clases también definen a partir de qué otra clase (o clases si se permite la herencia múltiple) esta clase hereda (y qué propiedades si existe herencia selectiva). Una vez que haya creado dicho plano, ahora puede generar una cantidad ilimitada de objetos de acuerdo con este modelo.
Sin embargo, hay lenguajes OO que no tienen clases. ¿Cómo se construyen los objetos? Bueno, por lo general de forma dinámica. Por ejemplo, puede crear un nuevo objeto en blanco y luego agregar dinámicamente la estructura interna, como variables de instancia o métodos (mensajes). O puede duplicar un objeto ya existente, con todas sus propiedades y luego modificarlo. O posiblemente fusionar dos objetos en uno nuevo. A diferencia de los lenguajes basados en clases, estos lenguajes son muy dinámicos, ya que puede generar objetos dinámicamente durante el tiempo de ejecución de formas que ni siquiera el desarrollador ha pensado al comenzar a escribir el código.
Por lo general, esta dinámica tiene un precio: cuanto más dinámico es el lenguaje, más objetos de memoria (RAM) desperdiciarán y más lento todo, ya que el flujo de programas también es extremadamente dinámico y es difícil para un compilador generar código eficaz si no tiene posibilidades. para predecir código o flujo de datos. Los compiladores JIT pueden optimizar algunas partes durante el tiempo de ejecución, una vez que conocen el flujo del programa, sin embargo, dado que estos idiomas son dinámicos, el flujo del programa puede cambiar en cualquier momento, lo que obliga al JIT a descartar todos los resultados de compilación y volver a compilar el mismo código una y otra vez.
Pero este es un pequeño detalle de implementación: no tiene nada que ver con el principio básico de OO. No se dice en ninguna parte que los objetos necesitan ser dinámicos o deben ser alterables durante el tiempo de ejecución. La Wikipedia lo dice bastante bien:
Las técnicas de programación pueden incluir características tales como ocultar información, abstracción de datos, encapsulación, modularidad, polimorfismo y herencia.
http://en.wikipedia.org/wiki/Object-oriented_programming
Ellos pueden o no pueden . Esto no es obligatorio. Obligatorio es solo la presencia de objetos y que deben tener formas de interactuar entre ellos (de lo contrario, los objetos serían inútiles si no pueden interactuar entre ellos).
Usted preguntó: "¿Puede alguien mostrarme un ejemplo de algo maravilloso que podría hacer con el rubí que no puedo hacer con c # y que ejemplifica este enfoque diferente?"
Un buen ejemplo es el registro activo, el ORM integrado en los rieles. Las clases de modelo se crean dinámicamente en tiempo de ejecución, en función del esquema de la base de datos.