¿Cuál es el beneficio de la programación orientada a objetos sobre la programación de procedimientos?

76

Estoy tratando de entender la diferencia entre lenguajes de procedimiento como C y lenguajes orientados a objetos como C ++. Nunca he usado C ++, pero he estado discutiendo con mis amigos sobre cómo diferenciar los dos.

Me han dicho que C ++ tiene conceptos orientados a objetos, así como modos públicos y privados para la definición de variables: cosas que C no tiene. Nunca tuve que usarlos para desarrollar programas en Visual Basic.NET: ¿cuáles son los beneficios de estos?

También me han dicho que si una variable es pública, se puede acceder a ella desde cualquier lugar, pero no está claro en qué se diferencia de una variable global en un lenguaje como C. Tampoco está claro en qué se diferencia una variable privada de una variable. variable local.

Otra cosa que he escuchado es que, por razones de seguridad, si se necesita acceder a una función, primero se debe heredar. El caso de uso es que un administrador solo debería tener todos los derechos que necesita y no todo, pero parece que un condicional también funcionaría:

if ( login == "admin") {
    // invoke the function
}

¿Por qué esto no es ideal?

Dado que parece haber una manera procesal de hacer todo orientado a objetos, ¿por qué debería preocuparme por la programación orientada a objetos?

    
pregunta niko 16.11.2011 - 06:20

12 respuestas

133

Hasta ahora, todas las respuestas se han centrado en el tema de su pregunta tal como se indica, que es "cuál es la diferencia entre c y c ++". En realidad, parece que sabes qué es la diferencia, simplemente no entiendes por qué necesitarías esa diferencia. Entonces, otras respuestas intentaron explicar la OO y la encapsulación.

Quería hacer una respuesta con otra respuesta, porque según los detalles de tu pregunta, creo que necesitas retroceder varios pasos.

No entiendes el propósito de C ++ u OO, porque para ti, parece que tu aplicación simplemente necesita almacenar datos. Estos datos se almacenan en variables. "¿Por qué querría hacer que una variable sea inaccesible? ¡Ahora no puedo acceder a ella! Al hacer que todo sea público, o mejor aún, global, puedo leer datos desde cualquier lugar y no hay problemas". - Y tiene razón, según la escala de los proyectos que está escribiendo actualmente, probablemente no haya muchos problemas (o los hay, pero aún no se ha dado cuenta de ellos).

Creo que la pregunta fundamental que realmente necesitas responder es: "¿Por qué querría ocultar los datos? ¡Si hago eso, no puedo trabajar con eso!" Y es por esto que:

Supongamos que inicia un nuevo proyecto, abre su editor de texto y comienza a escribir funciones. Cada vez que necesitas almacenar algo (para recordarlo más adelante), creas una variable. Para hacer las cosas más simples, haces tus variables globales. Su primera versión de su aplicación funciona muy bien. Ahora empiezas a agregar más características. Tiene más funciones, ciertos datos que almacenó antes deben leerse desde su nuevo código. Otras variables necesitan ser modificadas. Sigues escribiendo más funciones. Lo que puede haber notado (o, si no, lo notará en el futuro) es que, a medida que su código crece, le lleva más tiempo agregar la siguiente función. Y a medida que su código crece, cada vez es más difícil agregar funciones sin romper algo que solía funcionar. ¿Por qué? Porque necesita recordar qué todas están almacenando sus variables globales y necesita recordar dónde se están modificando todas . Y debe recordar qué función es aceptable para llamar en qué orden exacto y si los llama en un orden diferente , puede obtener errores porque sus variables globales no están bastante valido todavia ¿Alguna vez te has encontrado con esto?

¿Qué tan grandes son tus proyectos típicos (líneas de código)? Ahora imagina un proyecto de 5000 a 50000 veces más grande que el tuyo. Además, hay varias personas que trabajan en él. ¿Cómo pueden todos los miembros del equipo recordar (o incluso saber) qué están haciendo todas esas variables?

Lo que describí anteriormente es un ejemplo de código perfectamente acoplado. Y desde el principio de los tiempos (asumiendo que el tiempo comenzó el 1 de enero de 1970), la humanidad ha estado buscando formas de evitar estos problemas. La forma de evitarlos es dividiendo su código en sistemas, subsistemas y componentes y limitando la cantidad de funciones que tienen acceso a cualquier dato. Si tengo 5 enteros y una cadena que representa algún tipo de estado, ¿sería más fácil para mí trabajar con este estado si solo 5 funciones configuran / obtienen los valores? ¿O si 100 funciones configuran / obtienen estos mismos valores? Incluso sin lenguajes OO (es decir, C), las personas han estado trabajando duro para aislar los datos de otros datos y crear límites de separación limpios entre las diferentes partes del código. Cuando el proyecto alcanza un cierto tamaño, la facilidad de la programación no lo es, "puedo acceder a la variable X desde la función Y", pero "cómo me aseguro de que SOLO funcionen las funciones A, B, C y nadie más toque la variable X".

Esta es la razón por la que se han introducido los conceptos de OO y por eso son tan poderosos. Le permiten ocultar sus datos de usted mismo y desea hacerlo a propósito, ya que cuanto menor sea el código que vea esos datos, menor será la probabilidad de que cuando agregue la siguiente función, romper algo. Este es el propósito principal de los conceptos de encapsulación y programación OO. Le permiten dividir nuestros sistemas / subsistemas en cajas aún más granulares, hasta un punto donde, sin importar qué tan grande sea el proyecto en general, solo se puede acceder a un conjunto de variables dado por 50-200 líneas de código, ¡y eso es todo! Obviamente, hay mucho más en la programación de OO, pero, en esencia, esta es la razón por la que C ++ le ofrece opciones para declarar datos / funciones como privadas, protegidas o públicas.

La segunda gran idea en OO es el concepto de capas de abstracción. Aunque los lenguajes de procedimiento también pueden tener abstracciones, en C, un programador debe hacer un esfuerzo consciente para crear tales capas, pero en C ++, cuando declara una clase, crea automáticamente una capa de abstracción (aún depende de usted si esta abstracción agregará o quitará valor). Debería leer / investigar más sobre las capas de abstracción y, si tiene más preguntas, estoy seguro de que este foro también estará encantado de responderlas.

    
respondido por el DXM 16.11.2011 - 09:05
10

Hmm ... tal vez es mejor hacer una copia de seguridad e intentar dar una idea de la intención básica de la programación orientada a objetos. Gran parte de la intención de la programación orientada a objetos es permitir la creación de tipos de datos abstractos. Para un ejemplo realmente simple con el que sin duda estás familiarizado, considera una cadena. Una cadena normalmente tendrá un búfer para contener el contenido de la cadena, algunas funciones que pueden operar en la cadena (buscar en ella, acceder a partes de la misma, crear subcadenas, etc.) También (al menos típicamente) tendrá algo para manténgase al tanto de la longitud (actual) de la cadena y (probablemente) el tamaño del búfer, de modo que (por ejemplo) aumente el tamaño de la cadena de 1 a 1000000, sabrá cuándo se necesita más memoria para mantener la más grande contenido.

Esas variables (el búfer, la longitud actual y el tamaño del búfer) son privadas para la cadena en sí, pero no son locales para una función en particular. Cada cadena tiene un contenido de cierta longitud en particular, por lo que necesitamos rastrear ese contenido / longitud para esa cadena. A la inversa, la misma función (por ejemplo, para extraer una subcadena) puede operar en muchas cadenas diferentes en diferentes momentos, por lo que los datos no pueden ser locales a la función individual.

Como tal, terminamos con algunos datos que son privados para la cadena, por lo que solo es (directamente) accesible a las funciones de cadena. El mundo exterior puede obtener la longitud de la cadena usando una función de cadena, pero no necesita saber nada sobre los componentes internos de la cadena para obtenerla. Del mismo modo, puede modificar la cadena, pero nuevamente, lo hace a través de las funciones de la cadena, y solo ellos modifican directamente esas variables locales al objeto de la cadena.

En lo que respecta a la seguridad, observo que si bien esto es razonable como una analogía, no es no la forma en que realmente funcionan las cosas. En particular, el acceso en C ++ no es específicamente no destinado a cumplir con el mismo tipo de requisitos que el acceso en un sistema operativo. Se supone que un sistema operativo hace cumplir las restricciones para que (por ejemplo) un usuario normal no pueda hacer las cosas reservadas para un administrador. Por el contrario, el control de acceso en C ++ solo pretende evitar accidentes . Por diseño, cualquiera que quiera puede evitarlos con bastante facilidad. Están en el mismo orden en que marcan un archivo de solo lectura para que no lo borre accidentalmente. Si decide eliminar el archivo, es trivial cambiarlo de sólo lectura a lectura y escritura; todo lo que se configura en solo lectura es que al menos lo pienses un segundo y decide eliminar el archivo para que no se elimine por accidente solo al presionar la tecla equivocada en el momento equivocado .

    
respondido por el Jerry Coffin 16.11.2011 - 07:17
6

OOP versus C no es realmente sobre ninguna de las cosas que has discutido. Se trata principalmente de empaquetar el código en áreas que no se pueden / no pueden involuntariamente (o incluso a veces intencionalmente) afectarse entre sí.

C básicamente te permite ejecutar cualquier función desde cualquier lugar. OOP evita eso al agrupar los métodos en clases y solo le permite usar los métodos haciendo referencia a la clase que los contiene. Por lo tanto, una gran ventaja potencial de la OOP es que es mucho más probable que tenga un mejor arreglo de código sin mucha experiencia para decirle que debería.

    
respondido por el John Fisher 16.11.2011 - 07:18
4

Una clase bien escrita debe ser una pequeña "isla de confianza": puedes usarla y asumir que hace "lo correcto" y que te protege de las trampas comunes. Eso convierte a una buena clase en un bloque de construcción, que es mucho más reutilizable como un grupo de funciones y variables, que podrían funcionar bien pero mostrarle todas sus entrañas feas, y lo obligan a comprender cómo funcionan juntos, cómo deben inicializarse. Una buena clase debería ser como un conector USB, mientras que la solución de procedimiento es como un montón de cables, chips, estaño y un poco de soldadura.

Un punto que no se trató en profundidad es el aspecto de la interfaz / implementación. Una interfaz describe el comportamiento, pero no la realización. Por lo tanto, una interfaz de lista describe el concepto de una lista y su comportamiento: Usted esperaría cosas como los métodos de agregar, eliminar y dimensionar. Ahora hay muchas formas diferentes de implementar esta lista, por ejemplo, como una lista enlazada o usando un buffer de matriz. El poder de la programación OO es que al usar una interfaz puede razonar sobre el comportamiento sin saber sobre la implementación. El acceso a variables o métodos internos destruiría esta abstracción, no podría reemplazar una implementación de lista por otra y no podría mejorar una implementación existente sin tocar el código utilizando la clase. Esa es una de las razones principales por las que se necesitan variables y métodos privados: para proteger los detalles internos de la implementación, por lo que la abstracción permanece intacta.

OO va incluso un paso más allá: E.g. para las bibliotecas, puede definir una interfaz para cosas que aún no existen y escribir código que funcione con esa interfaz. Los usuarios pueden escribir clases implementando la interfaz y usar los servicios provistos por la biblioteca. Esto permite un grado de flexibilidad que no es posible con la programación de procedimientos.

    
respondido por el Landei 18.11.2011 - 10:01
3

Hay una manera de hacer todo con una máquina de Turing, o como mínimo en un lenguaje ensamblador para el código de máquina que un programa de C o C ++ finalmente compilará.

Entonces, la diferencia no se trata de lo que puede hacer el código, sino de lo que las personas pueden hacer.

La gente comete errores. Lotes.

OOP introduce un paradigma y una sintaxis que ayuda a reducir el tamaño y la densidad de probabilidad del espacio de posibles errores de codificación humana. A veces, cometiendo el error ilegal para una determinada clase de objeto de datos (por ejemplo, no es un método declarado para ese objeto). A veces, haciendo el error más detallado o estilísticamente extraño en comparación con el uso canónico del lenguaje. A veces, se requiere una interfaz con menos usos posibles inconsistentes o enredados (público frente a privado). etc.

Cuanto más grande sea el proyecto, mayor será la probabilidad de errores. Que un nuevo codificador no puede ser expuesto si solo tiene experiencia con programas pequeños. Por lo tanto, el desconcierto potencial de por qué la POO es valiosa.

    
respondido por el hotpaw2 16.11.2011 - 20:22
2

Su pregunta parece más relacionada con el propósito de la POO que con la diferencia. El concepto en tu post es encapsulación; y la encapsulación existe para apoyar el cambio. Cuando otras clases están accediendo a sus partes internas, se hace difícil modificarlas sin romperlas. En OOP, proporciona una interfaz (miembros públicos) a través de la cual permite que otras clases interactúen con la suya, y oculta sus elementos internos para que puedan ser modificados de forma segura.

    
respondido por el Eoin Carroll 16.11.2011 - 08:26
2
  

No importa donde lea las variables privadas no se puede acceder mientras que   Las variables públicas pueden ser entonces, ¿por qué no hacerlo público como global y privado?   como local cual es la diferencia? ¿Cuál es el uso real de público y   privado? Por favor, no digas que puede ser usado por todos, supongo por qué.   ¿No usamos algunas condiciones y hacemos las llamadas?

Espero que nunca quieras más de una cadena en tu aplicación. También espero que sus variables locales persistan entre las llamadas a funciones. ¿Estas cosas podrían ser iguales en términos de accesibilidad pero en términos de vida útil y otros usos? Absolutamente no son lo mismo.

    
respondido por el DeadMG 16.11.2011 - 08:30
1

Como muchos dijeron, cualquier programa, una vez compilado, se convierte en un código binario y, como una cadena binaria podría usarse para representar un número entero, cualquier programa es solo un número. Sin embargo, definir el número que necesita puede ser bastante difícil y es por eso que surgieron lenguajes de programación de alto nivel. Los lenguajes de programación son solo modelos del código ensamblador que eventualmente producen. Me gustaría explicarle la diferencia entre programación de procedimientos y OO a través de este excelente artículo sobre Programación orientada al contexto enlace

como puede ver en esta imagen, que se muestra en el documento, la programación de procedimientos proporciona solo una dimensión para asociar una unidad de cómputo con un nombre. Aquí, las llamadas o nombres de procedimientos se asignan directamente a las implementaciones de procedimientos. En la Figura-a, la llamada a m1 no deja más remedio que la invocación de la única implementación del procedimiento m1.

La programación orientada a objetos agrega otra dimensión para la resolución de nombres a la de la programación de procedimientos. Además del método o el nombre del procedimiento, el envío de mensajes tiene en cuenta el receptor del mensaje cuando se busca un método. En la Figura B vemos dos implementaciones del método m1. La selección del método apropiado no solo depende del nombre del mensaje m1, sino también del destinatario del mensaje real, aquí Ry.

Esto permite la encapsulación y modularización.

La Figura-c es, finalmente, sobre la programación orientada al sujeto que extiende el envío del método orientado a objetos en otra dimensión.

Espero que esto te haya ayudado a pensar en OOP desde una perspectiva diferente.

    
respondido por el Silli 16.11.2011 - 22:28
0

(+1) Hacer una pregunta sobre algo que no entiendes, es bueno, incluso si suena tonto.

La diferencia es Object & Programación orientada a la clase. "Plain C", trabaja con datos & funciones "C ++" agrega conceptos de "objetos y clases", además de varios conceptos secundarios relacionados.

Sin embargo, abogo por los desarrolladores para que aprendan "Plain C" antes de "C ++". O "Procesal Pascal" antes de "Objeto Pascal".

Muchos desarrolladores creen que los estudiantes deberían enseñar solo una cosa.

Por ejemplo, los maestros antiguos que no obtienen O.O., y solo enseñan "C estructurado simple".

O maestros "inconformistas" que enseñan solo O.O., pero no "Plain C", porque "no lo necesitas". O ambos, sin preocuparse por la orden de enseñanza.

Pienso que los estudiantes deberían aprender tanto la "C estructurada simple" como la "C orientada a objetos (C ++)". Con "Plain C", primero, y "C ++", más adelante.

En el mundo real, debes aprender ambos paradigmas (además de otros paradigmas, como "funcional").

Pensar en programas estructurados como un gran "objeto" de singleton puede ayudar.

También debe poner énfasis en los espacios de nombres ("módulos"), en ambos idiomas, muchos profesores simplemente lo ignoran, pero es importante.

    
respondido por el umlcat 16.11.2011 - 18:51
0

En una palabra, gestión de proyectos. Lo que quiero decir es que C ++ me ayuda a hacer cumplir las reglas de cómo otros utilizan mi código. Trabajando en un proyecto de 5.5 millones de líneas, encuentro la programación orientada a objetos muy útil. Otra ventaja es el compilador que me hace (y a todos los demás) seguir ciertas reglas y detectar errores menores en el tiempo de compilación. Todas las ventajas teóricas están ahí también, pero solo quería centrarme en las cosas prácticas cotidianas. Después de todo, todo se compila en código de máquina.

    
respondido por el Gus 18.11.2011 - 07:34
-1

La Programación Orientada a Objetos es la Programación de Procedimientos, con cuadros.

En PP, tienes un cuadro, un estado, que se vuelve increíblemente grande a medida que el proyecto crece, lo que provoca que aparezcan efectos secundarios cada vez que olvides un poco de ese gran estado.

En OO, tienes muchos cuadros, muchos estados y, a medida que el proyecto crece, los cuadros crecen un poco y el número de cuadros crece mucho.

Sigue siendo más fácil mirar cajas más pequeñas, es fácil tener la ilusión de una imagen completa, pero en realidad es casi imposible, ya que mirar clases e interfaces oculta los detalles de implementación que pueden tener ramificaciones importantes.

En la programación funcional, tiene muchos cuadros de funciones y decide que cada función tiene una entrada (parámetros) y una salida (retornos), sin ningún otro acceso al contexto externo.

Debido a que no hay estado ni efectos secundarios (por diseño), puede analizar de forma segura cualquier función por separado y saber al 100% cómo se comportará en cualquier circunstancia.

Debido a que está utilizando el código de boxeo por unidades lógicas que representan acciones, también es posible tener solo un cuadro por acción típica.

Esto reducirá el código de cualquier proyecto a gran escala en un factor enorme en comparación con la POO, que promueve el ocultamiento de múltiples funciones analógicas en toda la base de código en diferentes clases.

Esto también superará al PP por mucho, ya que puede hacer crecer el proyecto por mucho más tiempo, ya que no hay más estados XXXXXXXL para realizar un seguimiento.

En resumen, PP es probablemente la forma más sencilla de abordar un programa simple y FP es probablemente la forma más sencilla de abordar un programa complejo.

Si se tiene en cuenta el objetivo de unificar todas las bases de código y mejorar la reutilización del código, siempre se debe usar FP, ya que es el único paradigma que tiene sentido a gran escala, así como el único paradigma que tiene una capacidad de reutilización del 100%. (simplemente puede copiar y pegar una función y usarla en otro lugar, sin gastos generales).

Y obtienes pruebas de unidad 100% confiables de forma gratuita.

Y no tienes que escribir "final estática privada of_doom genius awesome string_1".

Y obtienes paralelismo gratis.

    
respondido por el Morg. 28.09.2013 - 09:22
-3

La simple diferencia de una oración es que C ++ es C con clases. (aunque ahora es mucho más) No entiendo por qué no quieres aprender las diferencias entre dos leyendo un gran artículo sobre C ++ en Wikipedia ... Este artículo te ayudará mucho: - C ++ (Wikipedia)

También googlear en el tema ayudará. Pedirle a personas al azar que expliquen esto podría ser complicado. En mi humilde opinión, uno entiende mejor leyendo que preguntando a alguien

    
respondido por el Pankaj Upadhyay 16.11.2011 - 06:59

Lea otras preguntas en las etiquetas