¿Por qué se afirma que la gente de C# no entiende la programación orientada a objetos?(vs orientado a clases)

StackOverflow https://stackoverflow.com/questions/52092

  •  09-06-2019
  •  | 
  •  

Pregunta

Esto me llamó la atención anoche.

en lo último Podcast de ALT.NET Scott Bellware analiza cómo, a diferencia de Ruby, lenguajes como c#, java et al.no están verdaderamente orientados a objetos, sino que optan por la frase "orientados a clases".Hablan de esta distinción en términos muy vagos sin entrar en muchos detalles ni discutir mucho los pros y los contras.

¿Cuál es la verdadera diferencia aquí y cuánto importa?¿Qué otros lenguajes están entonces "orientados a objetos"?Sonó bastante interesante, pero no quiero tener que aprender Ruby solo para saber si me falta algo.

Actualizar:Después de leer algunas de las respuestas a continuación, parece que la gente generalmente está de acuerdo en que la referencia es a escribir con pato.Sin embargo, lo que aún no estoy seguro de entender es la afirmación de que esto, en última instancia, cambia mucho.Especialmente si ya estás haciendo tdd correctamente con un acoplamiento flojo, bla, bla, bla.¿Alguien puede mostrarme un ejemplo de algo maravilloso que podría hacer con Ruby y que no puedo hacer con C# y que ejemplifica este enfoque diferente de OOP?

¿Fue útil?

Solución

Los comentarios sobre tipeo de pato aquí se atribuyen más al hecho de que Ruby y Python son más dinámica que C#.Realmente no tiene nada que ver con su OO Nature.

Lo que (creo) 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 agregarle/cambiar/eliminar comportamiento en tiempo de ejecución.

Otro buen ejemplo es que NULL también es un objeto.En Ruby, todo es LITERALMENTE un objeto.Tener una OO tan profunda en todo su ser permite algunas técnicas de metaprogramación divertidas como Method_missing.

Otros consejos

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 y sencillas de una abstracción determinada.En un lenguaje orientado a clases, como C#, por ejemplo, los objetos deben definirse mediante clases, y estas plantillas generalmente se enlatan, empaquetan y se hacen 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 la clase.

En mi opinión, realmente define demasiado "orientado a objetos", pero a lo que se refieren es a que Ruby, a diferencia de C#, C++, Java, et al, no hace uso de definiendo una clase: en realidad solo trabajas directamente con objetos.Por el contrario, en C#, por ejemplo, defines clases que entonces debes instanciar en objeto mediante la nueva palabra clave.El punto clave es que debes declarar una clase en C# o describirla.Además, en Ruby, todo (los números pares, por ejemplo) son un objeto.Por el contrario, C# aún conserva el concepto de tipo de objeto y tipo de valor.De hecho, creo que esto ilustra el punto que plantean sobre C# y otros lenguajes similares: tipo y valor tipo implicar un tipo sistema, lo que significa que tienes un sistema completo de describiendo tipos en lugar de simplemente trabajar con objetos.

Conceptualmente, creo que OO diseño es lo que proporciona la abstracción para abordar la complejidad de los sistemas de software en la actualidad.El lenguaje es una herramienta que se utiliza para implementar un diseño OO; algunos lo hacen más natural que otros.Todavía diría que desde una definición más común y amplia, C# y los demás todavía son orientado a objetos idiomas.

Hay tres pilares de la programación orientada a objetos

  1. Encapsulación
  2. Herencia
  3. Polimorfismo

Si un lenguaje puede hacer esas tres cosas, es un lenguaje OOP.

Estoy bastante seguro de que el argumento del lenguaje X hace la programación orientada a objetos mejor que el lenguaje A continuará para siempre.

OO a veces se define como orientado al mensaje.La idea es que una llamada a un método (o acceso a una propiedad) sea en realidad un mensaje enviado a otro objeto.La forma en que el objeto receptor maneja el mensaje está completamente encapsulada.A menudo el mensaje corresponde a un método que luego se ejecuta, pero eso es sólo un detalle de implementación.Por ejemplo, puede crear un controlador general que se ejecute independientemente del nombre del método en el mensaje.

La OO estática como en C# no tiene este tipo de encapsulación.Un masaje tiene para 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 de tipo estático no son verdaderos OO, ya que carecen de una encapsulación "verdadera".

Actualizar:Es la nueva ola..lo que sugiere que todo lo que hemos estado haciendo hasta ahora está pasado de moda.Parece estar apuntalando bastante en podcasts y libros.Quizás esto sea lo que escuchaste.

Hasta ahora nos hemos preocupado por las clases estáticas y no soltado El poder del desarrollo orientado a objetos.Hemos estado haciendo 'desarrollo basado en clase'. Las clases son plantillas fijas/estáticas para crear objetos.Todos los objetos de una clase son creados iguales.

p.ej.Sólo para ilustrar lo que he estado balbuceando...Permítanme tomar prestado un fragmento de código Ruby del screencast de PragProg que acabo de tener el privilegio de ver.El 'desarrollo basado en prototipos' desdibuja la línea entre objetos y 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 tradicional basada en clases.Te brinda más flexibilidad y control en ciertos escenarios "especiales" (que todavía tengo que comprender).Esto permite cosas como Mix-ins (reutilizar el comportamiento sin herencia de clases).

Al desafiar los primitivos básicos de cómo pensamos acerca de los problemas, la 'verdadera programación orientada a objetos' es como 'Matrix' en cierto modo...Sigues haciendo WTF en un bucle.Como éste..donde la clase base de Container puede ser una matriz o un hash según en qué lado de 0,5 esté 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 fuera de esto...leyendo y tratando de darle sentido a este nuevo fenómeno.Parece ser poderoso..muy poderoso..¿Útil?Necesito que mis ojos se abran un poco más.Tiempos interesantes..estos.

Solo escuché los primeros 6 o 7 minutos del podcast que generó tu pregunta.Si su intención es decir que C# no es un lenguaje puramente orientado a objetos, en realidad es 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 la "mecanografía de pato", así que no lo repetiré.

Si esta diferencia (todo lo que es un objeto versus todo lo que no es un objeto) es material o significativa es una pregunta que no puedo responder fácilmente porque no tengo suficiente profundidad en Ruby para compararlo con C#.Aquellos de ustedes que aquí conocen Smalltalk (yo no, aunque desearía saberlo) probablemente hayan estado mirando el movimiento Ruby con cierta diversión desde que fue el primer lenguaje OO puro hace 30 años.

¿Quizás estén aludiendo a la diferencia entre tipificación pato y jerarquías de clases?

Si camina como un pato y grazna como un pato, finge que es un pato y patéalo.

En C#, Java, etc.el compilador se preocupa mucho por:¿Se le permite realizar esta operación en ese objeto?

Orientado a objetos vs.Por lo tanto, Orientado a Clases podría significar:¿El lenguaje se preocupa por objetos o clases?

Por ejemplo:En Python, para implementar un objeto iterable, solo necesita proporcionar un método __iter__() que devuelve un objeto que tiene un método llamado next().Eso es todo al respecto:Sin implementación de interfaz (no existe tal cosa).Sin subclasificaciones.Simplemente hablando como un pato/iterador.

EDITAR: Esta publicación fue votada mientras reescribía todo.Lo siento, no volveré a hacer eso nunca más.El contenido original incluía consejos para aprender tantos idiomas como fuera posible y no preocuparse por lo que los doctores piensan o dicen sobre un idioma.

¡Ese sí que fue un podcast abstracto!
Pero ya veo a qué se refieren: simplemente los deslumbró Ruby Sparkle.Ruby te permite hacer cosas que los programadores basados ​​en C y Java ni siquiera pensarían + combinaciones de esas cosas te permiten lograr posibilidades inimaginables.Agregar nuevos métodos a una clase String incorporada porque te apetece, pasar bloques de código sin nombre para que otros los ejecuten, mezclar...La gente convencional no está acostumbrada a que los objetos se alejen demasiado de la plantilla de clase.Es un mundo completamente nuevo ahí fuera, seguro.

En cuanto a que los chicos de C# no son lo suficientemente OO...no te lo tomes en serio..Simplemente tómalo como lo que dices cuando te quedas 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 aprenda en la década actual...Sería Rubí.Me alegro de haberlo hecho..Aunque algunas personas pueden reclamar Python.Pero es como mi opinión...¡hombre!:D

No creo que se trate específicamente de escribir patos.Por ejemplo, C# ya admite la escritura de pato limitada; un ejemplo sería que puede usar foreach en cualquier clase que implementa MoveNext y Current.

El concepto de tipeo de pato es compatible con lenguajes de tipado estático como Java y C#, es básicamente una extensión de la reflexión.

Este es realmente el caso de escritura estática versus dinámica.Ambos son apropiados-OO, en la medida en que exista tal cosa.Fuera del mundo académico realmente no vale la pena debatir.

El código basura se puede escribir 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 y que el otro no pueda.

La verdadera diferencia está en la naturaleza de la codificación realizada.Los tipos estáticos reducen la libertad, pero la ventaja es que todos saben a qué se enfrentan.La oportunidad de cambiar de instancia sobre la marcha es muy poderosa, pero el costo es que resulta difícil saber con qué estás tratando.

Por ejemplo, para Java o C# Intellisense es fácil: el IDE puede producir rápidamente una lista desplegable 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 otra persona codificará, existe una ventaja real en la escritura estática.Para otros, como por ejemplo la producción rápida de prototipos, la ventaja es la dinámica.

Vale la pena comprender ambos en su caja de herramientas de habilidades, pero no es tan importante como comprender el que ya usa en profundidad.

Orientado a objetos 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 con el tiempo y que no estuvieron allí desde la primera hora) ya se han dado anteriormente, no los voy a repetir.Prefiero explicar esto de la manera más simple y no técnica posible.

La idea de la programación OO es que hay objetos.Los objetos son pequeñas entidades independientes.Estas entidades pueden tener información incorporada o no.Si disponen de dicha información, sólo la propia entidad puede acceder a ella o modificarla.Las entidades se comunican entre sí enviándose mensajes entre sí.Compare esto con los seres humanos.Los seres humanos son entidades independientes, tienen datos internos almacenados en su cerebro e interactúan entre sí comunicándose (p. ej.hablando uno al otro).Si necesita conocimiento del cerebro de otra persona, no puede acceder directamente a él, debe hacerle una pregunta y él puede responderle, diciéndole lo que quería saber.

Y eso es básicamente todo.Esta es una idea real detrás de la programación OO.Al escribir estas entidades, defina la comunicación entre ellas y haga que interactúen entre sí para formar una aplicación.Este concepto no está ligado a ningún idioma.Es sólo un concepto y si escribes tu código en C#, Java o Ruby, eso no es importante.Con un poco de trabajo extra, este concepto se puede hacer incluso en C puro, aunque es un lenguaje funcional pero ofrece todo lo necesario para el concepto.

Diferentes lenguajes han adoptado este concepto de programación OO y, por supuesto, los conceptos no siempre son iguales.Algunos idiomas permiten lo que otros prohíben, por ejemplo.Ahora uno de los conceptos involucrados es el concepto de clases.Algunos idiomas tienen clases, otros no.Una clase es un modelo de cómo se ve un objeto.Define el almacenamiento de datos interno de un objeto, define los mensajes que un objeto puede entender y si hay herencia (que es no es obligatorio para programación OO!), las clases también definen de qué otra clase (o clases si se permite la herencia múltiple) hereda esta clase (y qué propiedades si existe herencia selectiva).Una vez que haya creado dicho plano, ahora puede generar una cantidad ilimitada de objetos construidos de acuerdo con este plano.

Sin embargo, hay idiomas OO que no tienen clases.¿Cómo se construyen entonces los objetos?Bueno, normalmente de forma dinámica.P.ej.puede crear un nuevo objeto en blanco y luego agregarle dinámicamente una estructura interna como variables de instancia o métodos (mensajes).O puedes 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 en las que ni siquiera usted, el desarrollador, había pensado al comenzar a escribir el código.

Normalmente esta dinámica tiene un precio:Cuanto más dinámico sea un lenguaje, más memoria (RAM) desperdiciarán los objetos y más lento se volverá todo, ya que el flujo del programa también es extremadamente dinámico y es difícil para un compilador generar código efectivo si no tiene posibilidad de predecir el código o el flujo de datos.Los compiladores JIT pueden optimizar algunas partes de eso durante el tiempo de ejecución, una vez que conocen el flujo del programa; sin embargo, como estos lenguajes son tan dinámicos, el flujo del programa puede cambiar en cualquier momento, lo que obliga al JIT a desechar todos los resultados de la 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.En ninguna parte se dice que los objetos deban ser dinámicos o modificables durante el tiempo de ejecución.La Wikipedia lo dice bastante bien:

Las técnicas de programación pueden incluir características como ocultación de información, abstracción de datos, encapsulación, modularidad, polimorfismo y herencia.

http://en.wikipedia.org/wiki/Programación_orientada a objetos

Ellos puede o ellos podría no.Todo esto no es obligatorio.Lo único obligatorio es la presencia de objetos y que deben tener formas de interactuar entre sí (de lo contrario, los objetos serían bastante inútiles si no pueden interactuar entre sí).

Tu preguntaste:"¿Alguien puede mostrarme un ejemplo de algo maravilloso que podría hacer con Ruby y que no puedo hacer con C# y que ejemplifica este enfoque diferente de OOP?"

Un buen ejemplo es el registro activo, el ORM integrado en rieles.Las clases de modelo se crean dinámicamente en tiempo de ejecución, según el esquema de la base de datos.

Probablemente esto se trate de lo que estas personas ven que otros hacen en C# y Java en lugar de que C# y Java admitan programación orientada a objetos.La mayoría de los lenguajes se pueden utilizar en diferentes paradigmas de programación.Por ejemplo, puede escribir código de procedimiento en C# y Scheme, y puede realizar programación de estilo funcional en Java.Se trata más de lo que intentas hacer y de lo que admite el idioma.

Intentaré esto.

Python y Ruby son de tipo pato.Para generar cualquier código mantenible en estos lenguajes, es necesario utilizar un desarrollo basado en pruebas.Como tal, es muy importante para un desarrollador inyectar fácilmente dependencias en su código sin tener que crear un marco de soporte gigante.

La inyección de dependencia exitosa depende de tener un modelo de objetos bastante bueno.Los dos son una especie de dos caras de la misma moneda.Si realmente entiendes cómo usar la programación orientada a objetos, entonces deberías crear diseños de forma predeterminada donde las dependencias se puedan inyectar fácilmente.

Debido a que la inyección de dependencia es más fácil en lenguajes de tipo dinámico, los desarrolladores de Ruby/Python sienten que su lenguaje comprende las lecciones de OO mucho mejor que otros homólogos de tipo estático.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top