En programación , una clase es una estructura de entidad sintáctica que se utiliza para crear objetos . [ 1 ] : 1.3.3 Las capacidades de una clase difieren entre lenguajes de programación , pero generalmente los aspectos compartidos consisten en estado ( variables ) y comportamiento ( métodos ) que están asociados a un objeto en particular o a todos los objetos de esa clase. [ 2 ] [ 3 ]
El estado de un objeto puede diferir entre cada instancia de la clase, mientras que el estado de la clase es compartido por todas ellas. Los métodos de objeto incluyen acceso al estado del objeto (a través de un parámetro implícito o explícito que hace referencia al objeto), mientras que los métodos de clase no.
Si el lenguaje admite la herencia , se puede definir una clase a partir de otra clase, conservando todo su estado y comportamiento, además de un estado y comportamiento adicionales que la especializan aún más. La clase especializada es una subclase , y la clase en la que se basa es su superclase .
En lenguajes de programación puramente orientados a objetos, como Java y C# , todas las clases pueden formar parte de un árbol de herencia tal que la clase raíz es Object, lo que significa que todas las instancias de objetos son de Objecto extienden implícitamente Object, que se denomina tipo superior .
Historia
El concepto se introdujo principalmente en la programación orientada a objetos mediante el lenguaje Simula en la década de 1960 y se ha utilizado de forma continua en muchos lenguajes de programación desde entonces. [ 1 ] : 1.3.3 Su creación se basó en un concepto similar al del bloque utilizado en el lenguaje de programación ALGOL 68 basado en prior . [ 1 ] : 1.3.2
Atributos
Ciclo de vida del objeto
Como instancia de una clase, un objeto se construye a partir de una clase mediante instanciación . Se asigna e inicializa memoria para el estado del objeto y se proporciona una referencia al objeto al código que lo utiliza. El objeto se puede usar hasta que se destruye ; su memoria de estado se libera.
La mayoría de los lenguajes permiten lógica personalizada en los eventos del ciclo de vida a través de un constructor y un destructor .
Tipo
Un objeto expresa el tipo de datos como una interfaz : el tipo de cada variable miembro y la firma de cada función miembro (método). Una clase define una implementación de una interfaz, y la instanciación de la clase da como resultado un objeto que expone la implementación a través de la interfaz. [ 4 ] En términos de teoría de tipos, una clase es una implementación — unaestructura de datos concreta y una colección de subrutinas —mientras que un tipo es una interfaz . Diferentes clases (concretas) pueden producir objetos del mismo tipo ( abstracto ) (dependiendo del sistema de tipos). Por ejemplo, el tipo (interfaz) Stack podría ser implementado por SmallStack , que es rápido para pilas pequeñas pero escala mal, y ScalableStack , que escala bien pero tiene una sobrecarga alta para pilas pequeñas.
Estructura

Una clase contiene campos de datos descritos sintácticamente (o propiedades , campos , miembros de datos o atributos ). [ 1 ] Estos suelen ser tipos y nombres de campos que se asociarán con variables de estado durante la ejecución del programa; estas variables de estado pertenecen a la clase o a instancias específicas de la clase. En la mayoría de los lenguajes, la estructura definida por la clase determina la distribución de la memoria utilizada por sus instancias. Son posibles otras implementaciones: por ejemplo, los objetos en Python utilizan contenedores asociativos de clave-valor. [ 5 ]
Algunos lenguajes de programación, como Eiffel, permiten especificar invariantes como parte de la definición de la clase y las garantizan mediante el sistema de tipos. La encapsulación del estado es necesaria para poder garantizar las invariantes de la clase.
Comportamiento
El comportamiento (o acción [ 1 ] ) de una clase o sus instancias se define mediante métodos . Los métodos son subrutinas con la capacidad de operar sobre objetos o clases. Estas operaciones pueden alterar el estado de un objeto o simplemente proporcionar formas de acceder a él. [ 6 ] Existen muchos tipos de métodos, pero su compatibilidad varía entre lenguajes. Algunos tipos de métodos son creados y llamados por el código del programador, mientras que otros métodos especiales, como constructores, destructores y operadores de conversión, son creados y llamados por el código generado por el compilador. Un lenguaje también puede permitir al programador definir y llamar a estos métodos especiales. [ 7 ] [ 8 ]
Interfaz
Cada clase implementa (o realiza ) una interfaz al proporcionar estructura y comportamiento. La estructura consiste en datos y estado, y el comportamiento consiste en código que especifica cómo se implementan los métodos. [ 9 ] Existe una distinción entre la definición de una interfaz y la implementación de esa interfaz; sin embargo, esta línea se difumina en muchos lenguajes de programación porque las declaraciones de clase definen e implementan una interfaz. Algunos lenguajes, no obstante, proporcionan características que separan la interfaz de la implementación. Por ejemplo, una clase abstracta puede definir una interfaz sin proporcionar una implementación.
Los lenguajes que admiten la herencia de clases también permiten que las clases hereden interfaces de las clases de las que derivan.
Por ejemplo, si " " hereda de " " y si " " implementa la interfaz " " entonces " " también implementa la funcionalidad (constantes y declaración de métodos) proporcionada por " ".classZclassYclassYinterfaceXclassZinterfaceX
En los lenguajes que admiten especificadores de acceso , la interfaz de una clase se considera el conjunto de miembros públicos de la clase, incluidos tanto los métodos como los atributos (a través de métodos getter y setter implícitos ); no se pretende que el código externo dependa de los miembros privados o las estructuras de datos internas, por lo que no forman parte de la interfaz.
La metodología de programación orientada a objetos establece que las operaciones de cualquier interfaz de una clase deben ser independientes entre sí. Esto da como resultado un diseño por capas donde los clientes de una interfaz utilizan los métodos declarados en ella. Una interfaz no exige que los clientes invoquen las operaciones de una interfaz en un orden específico. Este enfoque tiene la ventaja de que el código del cliente puede asumir que las operaciones de una interfaz están disponibles siempre que el cliente tenga acceso al objeto. [ 10 ]
Ejemplo de interfaz
Los botones en el panel frontal de tu televisor son la interfaz entre tú y el cableado eléctrico al otro lado de su carcasa de plástico. Presionas el botón de encendido para encender y apagar el televisor. En este ejemplo, tu televisor en particular es la instancia, cada método está representado por un botón, y todos los botones juntos componen la interfaz (otros televisores del mismo modelo que el tuyo tendrían la misma interfaz). En su forma más común, una interfaz es la especificación de un grupo de métodos relacionados sin ninguna implementación asociada de dichos métodos.
Un televisor también posee una gran variedad de atributos , como el tamaño y la capacidad de emitir en color, que en conjunto conforman su estructura. Una clase representa la descripción completa de un televisor, incluyendo sus atributos (estructura) y botones (interfaz).
Obtener el número total de televisores fabricados podría ser un método estático de la clase `televisor`. Este método está asociado a la clase, pero se encuentra fuera del dominio de cada instancia de la misma. Otro ejemplo sería un método estático que busca una instancia específica dentro del conjunto de todos los objetos `televisor`.
Accesibilidad para miembros
El siguiente es un conjunto común de especificadores de acceso : [ 11 ]
- El modo privado (o de clase ) restringe el acceso a la clase misma. Solo los métodos que forman parte de la misma clase pueden acceder a los miembros privados.
- El modo protegido (o protegido por clase ) permite que la propia clase y todas sus subclases accedan al miembro.
- Público significa que cualquier código puede acceder al miembro por su nombre.
Si bien muchos lenguajes orientados a objetos admiten los especificadores de acceso mencionados anteriormente, su semántica puede diferir.
El diseño orientado a objetos utiliza los especificadores de acceso junto con un diseño cuidadoso de las implementaciones de métodos públicos para garantizar las invariantes de clase, es decir, las restricciones sobre el estado de los objetos. Un uso común de los especificadores de acceso es separar los datos internos de una clase de su interfaz: la estructura interna se hace privada, mientras que los métodos de acceso públicos se pueden usar para inspeccionar o modificar dichos datos privados.
Los especificadores de acceso no necesariamente controlan la visibilidad , ya que incluso los miembros privados pueden ser visibles para el código externo del cliente. En algunos lenguajes, se puede hacer referencia a un miembro inaccesible pero visible en tiempo de ejecución (por ejemplo, mediante un puntero devuelto por una función miembro), pero el verificador de tipos impedirá cualquier intento de usarlo haciendo referencia al nombre del miembro desde el código del cliente. [ 12 ]
Los distintos lenguajes de programación orientados a objetos imponen la accesibilidad y visibilidad de los miembros en diversos grados, y dependiendo del sistema de tipos y las políticas de compilación del lenguaje, se aplican en tiempo de compilación o en tiempo de ejecución . Por ejemplo, el lenguaje Java no permite que se compile el código cliente que accede a los datos privados de una clase. [ 13 ] En el lenguaje C++ , los métodos privados son visibles, pero no accesibles en la interfaz; sin embargo, pueden hacerse invisibles declarando explícitamente clases completamente abstractas que representen las interfaces de la clase. [ 14 ]
Algunos idiomas cuentan con otros sistemas de accesibilidad:
- Accesibilidad por instancia frente a accesibilidad por clase : Ruby admite los especificadores de acceso instance-private e instance-protected en lugar de class-private y class-protected, respectivamente. Se diferencian en que restringen el acceso en función de la instancia misma, en lugar de la clase de la instancia. [ 15 ]
- Friend : C++ admite un mecanismo mediante el cual una función declarada explícitamente como función amiga de la clase puede acceder a los miembros designados como privados o protegidos. [ 16 ]
- Basado en rutas : Java admite restringir el acceso a un miembro dentro de un paquete Java , que es la ruta lógica del archivo. Sin embargo, es una práctica común al extender un framework Java implementar clases en el mismo paquete que una clase del framework para acceder a miembros protegidos. El archivo fuente puede existir en una ubicación completamente diferente y puede desplegarse en un archivo .jar diferente , pero aún así estar en la misma ruta lógica en lo que respecta a la JVM. [ 11 ]
Herencia
Conceptualmente, una superclase es un superconjunto de sus subclases. Por ejemplo, GraphicObjectpodría ser una superclase de Rectangley Ellipse, mientras Squareque sería una subclase de Rectangle. Estas son también relaciones de subconjunto en la teoría de conjuntos; es decir, todos los cuadrados son rectángulos, pero no todos los rectángulos son cuadrados.
Un error conceptual común consiste en confundir una parte de una relación con una subclase. Por ejemplo, un coche y un camión son ambos tipos de vehículos, y sería apropiado modelarlos como subclases de la clase Vehículo. Sin embargo, sería un error modelar las partes del coche como relaciones de subclase. Por ejemplo, un coche se compone de un motor y una carrocería, pero no sería apropiado modelar un motor o una carrocería como subclases de un coche.
En el modelado orientado a objetos, este tipo de relaciones se modelan típicamente como propiedades de objetos. En este ejemplo, la Carclase tendría una propiedad llamada parts. partsestaría tipificada para contener una colección de objetos, como instancias de Body, Engine, Tires, etc. Los lenguajes de modelado de objetos como UML incluyen capacidades para modelar varios aspectos de las relaciones de "parte de" y otros tipos de relaciones: datos como la cardinalidad de los objetos, restricciones en los valores de entrada y salida, etc. Esta información puede ser utilizada por las herramientas de desarrollo para generar código adicional además de las definiciones de datos básicas para los objetos, como la comprobación de errores en los métodos get y set . [ 17 ]
Una cuestión importante al modelar e implementar un sistema de clases de objetos es si una clase puede tener una o más superclases. En el mundo real, con conjuntos reales, sería raro encontrar conjuntos que no se intersecten con más de un conjunto. Sin embargo, si bien algunos sistemas como Flavors y CLOS proporcionan la capacidad de que más de un padre lo haga en tiempo de ejecución, esto introduce una complejidad que muchos en la comunidad orientada a objetos consideran contraria a los objetivos de usar clases de objetos en primer lugar. Entender qué clase será responsable de manejar un mensaje puede volverse complejo cuando se trata de más de una superclase. Si se usa descuidadamente, esta característica puede introducir parte de la misma complejidad y ambigüedad del sistema que las clases fueron diseñadas para evitar. [ 18 ]
La mayoría de los lenguajes modernos orientados a objetos, como Smalltalk y Java, requieren herencia simple en tiempo de ejecución. Para estos lenguajes, la herencia múltiple puede ser útil para el modelado, pero no para la implementación.
Sin embargo, los objetos de las aplicaciones web semánticas sí tienen múltiples superclases. La volatilidad de Internet exige este nivel de flexibilidad, y los estándares tecnológicos como el Lenguaje de Ontología Web (OWL) están diseñados para soportarlo.
Un problema similar es si la jerarquía de clases puede modificarse en tiempo de ejecución. Lenguajes como Flavors, CLOS y Smalltalk admiten esta característica como parte de sus protocolos de meta-objetos . Dado que las clases son objetos de primera clase, es posible que modifiquen dinámicamente su estructura enviándoles los mensajes apropiados. Otros lenguajes que se centran más en el tipado fuerte, como Java y C++, no permiten que la jerarquía de clases se modifique en tiempo de ejecución. Los objetos de la web semántica tienen la capacidad de realizar cambios en las clases en tiempo de ejecución. La lógica es similar a la justificación para permitir múltiples superclases: Internet es tan dinámico y flexible que se requieren cambios dinámicos en la jerarquía para gestionar esta volatilidad. [ 19 ]
Si bien muchos lenguajes basados en clases admiten la herencia, esta no es una característica intrínseca de las clases. Un lenguaje basado en objetos (por ejemplo, Visual Basic clásico ) admite clases, pero no herencia.
Relaciones entre clases
Un lenguaje de programación puede admitir diversas características de relación de clases.
Composición
Las clases pueden estar compuestas de otras clases, estableciendo así una relación de composición entre la clase contenedora y sus clases incrustadas. La relación de composición entre clases también se conoce comúnmente como una relación "tiene un" . [ 20 ] Por ejemplo, una clase Carpodría estar compuesta de y contener una clase Engine. Por lo tanto, una Cartiene unEngine . Un aspecto de la composición es la contención, que es el encapsulamiento de instancias de componentes por la instancia que las contiene. Si un objeto contenedor contiene instancias de componentes por valor, los componentes y su objeto contenedor tienen una vida útil similar . Si los componentes están contenidos por referencia, es posible que no tengan una vida útil similar. [ 21 ] Por ejemplo, en Objective-C 2.0:
@interface Coche : NSObject@property NSString * nombre ; @property Engine * motor @property NSArray * neumáticos ;@finEsta clase Car tiene una instancia de NSString (un objeto de cadena ), Engine y NSArray (un objeto de matriz).
Jerárquico
Las clases pueden derivarse de una o más clases existentes, estableciendo así una relación jerárquica entre las clases derivadas ( clases base , clases padre osuperclases ) y la clase derivada (clase hijaosubclase). La relación de la clase derivada con las clases derivadas se conoce comúnmente como unarelación "es un" . [ 22 ] Por ejemplo, una clase "Botón" podría derivarse de una clase "Control". Por lo tanto, un Botónes unControl. Los miembros estructurales y de comportamiento de las clases padre sonheredadospor la clase hija. Las clases derivadas pueden definir miembros estructurales adicionales (campos de datos) y miembros de comportamiento (métodos) además de los queheredany, por lo tanto, sonespecializacionesde sus superclases. Además, las clases derivadas puedensobrescribirmétodos heredados si el lenguaje lo permite.
No todos los lenguajes admiten la herencia múltiple. Por ejemplo, Java permite que una clase implemente múltiples interfaces, pero solo herede de una clase. [ 23 ] Si se permite la herencia múltiple, la jerarquía es un grafo acíclico dirigido (o DAG, por sus siglas en inglés); de lo contrario, es un árbol . La jerarquía tiene clases como nodos y relaciones de herencia como enlaces. Es más probable que las clases del mismo nivel estén asociadas que las clases de diferentes niveles. Los niveles de esta jerarquía se denominan capas o niveles de abstracción.
Ejemplo (código Objective-C 2.0 simplificado, del SDK de iPhone):
@interface UIResponder : NSObject //... @interface UIView : UIResponder //... @interface UIScrollView : UIView //... @interface UITableView : UIScrollView //...En este ejemplo, una UITableView es una UIScrollView es una UIView es una UIResponder es un NSObject.
Modelado
En el análisis orientado a objetos y en el Lenguaje Unificado de Modelado (UML), una asociación entre dos clases representa una colaboración entre las clases o sus instancias correspondientes. Las asociaciones tienen dirección; por ejemplo, una asociación bidireccional entre dos clases indica que ambas clases son conscientes de su relación. [ 24 ] Las asociaciones pueden etiquetarse según su nombre o propósito. [ 25 ]
Un rol de asociación se asigna al final de una asociación y describe el rol de la clase correspondiente. Por ejemplo, un rol de "suscriptor" describe la forma en que las instancias de la clase "Persona" participan en una asociación de "suscripción" con la clase "Revista". Asimismo, una "Revista" tiene el rol de "revista suscrita" en la misma asociación. La multiplicidad del rol de asociación describe cuántas instancias corresponden a cada instancia de la otra clase de la asociación. Las multiplicidades comunes son "0..1", "1..1", "1..*" y "0..*", donde el "*" especifica cualquier número de instancias. [ 24 ]
Taxonomía
Existen muchas categorías de clases, algunas de las cuales se superponen.
Abstracto y concreto
En un lenguaje que admite herencia, una clase abstracta , o clase base abstracta ( ABC ), es una clase que no puede instanciarse directamente. Por el contrario, una clase concreta es una clase que sí puede instanciarse directamente. La instanciación de una clase abstracta solo puede ocurrir indirectamente, a través de una subclase concreta .
Una clase abstracta se etiqueta explícitamente como tal o simplemente especifica métodos abstractos (o virtuales ). Una clase abstracta puede proporcionar implementaciones de algunos métodos y también especificar métodos virtuales mediante firmas que deben ser implementadas por descendientes directos o indirectos de la clase abstracta. Antes de que una clase derivada de una clase abstracta pueda ser instanciada, todos los métodos abstractos de sus clases padre deben ser implementados por alguna clase en la cadena de derivación. [ 26 ]
La mayoría de los lenguajes de programación orientados a objetos permiten al programador especificar qué clases se consideran abstractas y no permiten su instanciación. Por ejemplo, en Java , C# y PHP , se utiliza la palabra reservada (keyword) `abstract` . [ 27 ] [ 28 ] En C++ , una clase abstracta es una clase que tiene al menos un método abstracto dado por la sintaxis apropiada en ese lenguaje (una función virtual pura en la terminología de C++). [ 26 ]abstract
Una clase que consta únicamente de métodos virtuales puros se denomina clase base abstracta pura (o ABC pura ) en C++ y también se conoce como interfaz entre los usuarios del lenguaje. [ 14 ] Otros lenguajes, en particular Java y C#, admiten una variante de clases abstractas llamada interfaz mediante una palabra clave del lenguaje. En estos lenguajes, no se permite la herencia múltiple , pero una clase puede implementar múltiples interfaces. Dicha clase solo puede contener métodos abstractos de acceso público. [ 23 ] [ 29 ] [ 30 ]
Local e interior
En algunos lenguajes de programación, las clases se pueden declarar en ámbitos distintos al ámbito global. Existen varios tipos de estas clases.
Una clase interna es una clase definida dentro de otra clase. La relación entre una clase interna y su clase contenedora también puede tratarse como otro tipo de asociación de clases. Una clase interna normalmente no está asociada con instancias de la clase contenedora ni se instancia junto con ella. Dependiendo del lenguaje, puede ser posible o no referirse a la clase desde fuera de la clase contenedora. Un concepto relacionado son los tipos internos , también conocidos como tipos de datos internos o tipos anidados , que son una generalización del concepto de clases internas. C++ es un ejemplo de un lenguaje que admite tanto clases internas como tipos internos (mediante declaraciones typedef ). [ 31 ] [ 32 ]
Una clase local es una clase definida dentro de un procedimiento o función. Esta estructura limita las referencias al nombre de la clase al ámbito donde se declara. Dependiendo de las reglas semánticas del lenguaje, puede haber restricciones adicionales para las clases locales en comparación con las no locales. Una restricción común es impedir que los métodos de una clase local accedan a las variables locales de la función que la contiene. Por ejemplo, en C++, una clase local puede hacer referencia a variables estáticas declaradas dentro de su función contenedora, pero no puede acceder a las variables automáticas de la función . [ 33 ]
Metaclase
Una metaclase es una clase cuyas instancias son clases. [ 34 ] Una metaclase describe una estructura común de una colección de clases y puede implementar un patrón de diseño o describir tipos particulares de clases. Las metaclases se utilizan a menudo para describir marcos de trabajo . [ 35 ]
En algunos lenguajes, como Python , Ruby o Smalltalk , una clase también es un objeto; por lo tanto, cada clase es una instancia de una metaclase única que está integrada en el lenguaje. [ 5 ] [ 36 ] [ 37 ] El Common Lisp Object System (CLOS) proporciona protocolos de metaobjetos (MOP) para implementar esas clases y metaclases. [ 38 ]
Final
Una clase final no puede ser subclaseada. Es básicamente lo opuesto a una clase abstracta, que debe ser subclaseada para su uso y no puede ser instanciada directamente. Una clase final es implícitamente una clase concreta y puede ser instanciada directamente.
Una clase se declara como final mediante la palabra clave finalen Java, C++ o PHP, o sealeden C#. Sin embargo, este concepto no debe confundirse con las clases en Java calificadas con la palabra clave sealed, que solo permiten la herencia de subclases seleccionadas. [ 39 ] [ 40 ] [ 41 ] [ 42 ] En lenguajes como Kotlin , todas las clases son finales por defecto, mientras que para permitir que una clase sea heredada, debe marcarse como open. [ 43 ]
Por ejemplo, la clase de Java está marcada como . [ 44 ]Stringfinal
Las clases finales pueden permitir que un compilador realice optimizaciones que no están disponibles para las clases que pueden ser subclasadas. [ 45 ]
Sellado
Una "clase sellada" es una clase que restringe la herencia a una lista seleccionada de clases. No debe confundirse con la sealedpalabra clave en C#, que denota una clase final. La lista de clases permitidas que la clase sellada puede heredar se especifica mediante una permitscláusula. [ 46 ]
public sealed class Quadrilateral extends Shape implements Renderable , Transformable , Comparable < Quadrilateral > , Measurable permits Parallelogram , Trapezoid , Kite { // ... }non-sealedes otra palabra clave que se utiliza para declarar que una clase o interfaz que extiende una clase sellada puede ser extendida por clases desconocidas. [ 47 ]
sealed class Parallelogram extends Quadrilateral { /* ... */ } sealed class Rectangle extends Parallelogram { /* ... */ }clase no sellada Cuadrado extiende Rectángulo { /* ... * / }// Dado que Square no es una clase sellada, cualquier clase puede heredar de ella. class RedSquare extends Square { /* ... */ }Abierto
Una clase abierta puede modificarse. Por lo general, los clientes no pueden modificar un programa ejecutable . Los desarrolladores suelen poder modificar algunas clases, pero normalmente no pueden modificar las clases estándar o integradas. En Ruby , todas las clases son abiertas. En Python , las clases se pueden crear en tiempo de ejecución y todas se pueden modificar posteriormente. [ 48 ] Las categorías de Objective-C permiten al programador añadir métodos a una clase existente sin necesidad de recompilarla ni siquiera tener acceso a su código fuente.
Mezclar
Algunos lenguajes ofrecen soporte especial para mixins , aunque en cualquier lenguaje con herencia múltiple, un mixin es simplemente una clase que no representa una relación de tipo "es un". Los mixins se utilizan normalmente para añadir los mismos métodos a varias clases; por ejemplo, una clase UnicodeConversionMixinpodría proporcionar un método que se llama unicodeToAscii()cuando se incluye en clases FileReaderque WebPageScraperno comparten un padre común.
Parcial
En los lenguajes que admiten esta característica, una clase parcial es una clase cuya definición puede dividirse en varias partes, dentro de un único archivo de código fuente o en varios archivos. [ 49 ] Las partes se fusionan en tiempo de compilación, lo que hace que la salida del compilador sea la misma que para una clase no parcial.
La principal motivación para la introducción de clases parciales es facilitar la implementación de generadores de código , como los diseñadores visuales . [ 49 ] De lo contrario, resulta un desafío o una solución de compromiso desarrollar generadores de código que puedan gestionar el código generado cuando este se intercala dentro del código escrito por el desarrollador. Mediante clases parciales, un generador de código puede procesar un archivo independiente o una clase parcial de grano grueso dentro de un archivo, lo que evita la compleja interposición del código generado mediante un análisis extenso, aumentando la eficiencia del compilador y eliminando el riesgo potencial de corromper el código del desarrollador. En una implementación simple de clases parciales, el compilador puede realizar una fase de precompilación donde "unifica" todas las partes de una clase parcial. Luego, la compilación puede proceder como de costumbre. [ 50 ]
Otros beneficios y efectos de la función de clase parcial incluyen:
- Permite separar la interfaz de una clase del código de implementación de una manera única.
- Facilita la navegación por clases extensas dentro de un editor .
- Permite la separación de responsabilidades , de forma similar a la programación orientada a aspectos, pero sin utilizar herramientas adicionales.
- Permite que varios desarrolladores trabajen en una misma clase simultáneamente sin necesidad de fusionar el código individual en un solo archivo posteriormente.
Las clases parciales han existido en Smalltalk bajo el nombre de extensiones de clase durante bastante tiempo. Con la llegada del .NET Framework 2 , Microsoft introdujo las clases parciales, compatibles tanto con C# 2.0 como con Visual Basic 2005. WinRT también admite clases parciales. [ 51 ]
No instantáneo
Las clases no instanciables permiten a los programadores agrupar campos y métodos propios de la clase que son accesibles en tiempo de ejecución sin necesidad de una instancia de la misma. De hecho, la instanciación está prohibida para este tipo de clases.
Por ejemplo, en C#, una clase marcada staticno puede ser instanciada, solo puede tener miembros estáticos (campos, métodos, otros), no puede tener constructores de instancia y es sealed(es final). [ 52 ]
Sin nombre
Una clase sin nombre o una clase anónima no está vinculada a un nombre o identificador al definirse. [ 53 ] [ 54 ] Esto es análogo a las funciones con nombre frente a las funciones sin nombre .
interfaz Saludo { void decirHola (); }// Clase anónima que implementa Greeting Greeting myGreeting = new Greeting () { @Override public void sayHello () { System . out . println ( "¡Hola desde una clase anónima!" ); } };miSaludo.decirHola ( ) ;Beneficios
Los beneficios de organizar el software en clases de objetos se dividen en tres categorías: [ 55 ]
- Desarrollo rápido
- Facilidad de mantenimiento
- Reutilización de código y diseños
Las clases de objetos facilitan el desarrollo rápido porque reducen la brecha semántica entre el código y los usuarios. Los analistas de sistemas pueden comunicarse tanto con desarrolladores como con usuarios utilizando prácticamente el mismo vocabulario, hablando de cuentas, clientes, facturas, etc. Las clases de objetos suelen facilitar el desarrollo rápido porque la mayoría de los entornos orientados a objetos incluyen potentes herramientas de depuración y prueba. Las instancias de las clases se pueden inspeccionar en tiempo de ejecución para verificar que el sistema funcione como se espera. Además, en lugar de obtener volcados de memoria principal, la mayoría de los entornos orientados a objetos cuentan con capacidades de depuración interpretadas, lo que permite al desarrollador analizar con precisión dónde se produjo el error en el programa y ver qué métodos se llamaron con qué argumentos. [ 56 ]
Las clases de objetos facilitan el mantenimiento mediante la encapsulación. Cuando los desarrolladores necesitan modificar el comportamiento de un objeto, pueden limitar el cambio únicamente a ese objeto y sus componentes. Esto reduce la posibilidad de efectos secundarios no deseados derivados de las mejoras de mantenimiento.
La reutilización de software es también una gran ventaja del uso de clases de objetos. Las clases facilitan la reutilización mediante herencia e interfaces. Cuando se requiere un nuevo comportamiento, a menudo se puede lograr creando una nueva clase que herede los comportamientos y datos predeterminados de su superclase y, posteriormente, adaptando algún aspecto del comportamiento o los datos según sea necesario. La reutilización mediante interfaces (también conocidas como métodos) se produce cuando otro objeto desea invocar (en lugar de crear un nuevo tipo de) alguna clase de objeto. Este método de reutilización elimina muchos de los errores comunes que pueden introducirse en el software cuando un programa reutiliza código de otro. [ 57 ]
Representación en tiempo de ejecución
Como tipo de dato, una clase se considera generalmente una construcción de tiempo de compilación. [ 58 ] Un lenguaje o biblioteca también puede admitir metaobjetos de prototipo o fábrica que representan información de tiempo de ejecución sobre las clases, o incluso metadatos que proporcionan acceso a las funcionalidades de programación reflexiva (reflexión) y la capacidad de manipular formatos de estructuras de datos en tiempo de ejecución. Muchos lenguajes distinguen este tipo de información de tipo de tiempo de ejecución sobre las clases de una clase en sí misma, basándose en que la información no es necesaria en tiempo de ejecución. Algunos lenguajes dinámicos no hacen distinciones estrictas entre construcciones de tiempo de ejecución y de tiempo de compilación, y por lo tanto pueden no distinguir entre metaobjetos y clases.
Por ejemplo, si Human es un metaobjeto que representa la clase Person, entonces se pueden crear instancias de la clase Person utilizando las funcionalidades del metaobjeto Human .
Programación basada en clases
La programación basada en clases , o más comúnmente orientada a clases , es un estilo de programación orientada a objetos en el que todos los objetos son creados por una clase y sin herencia entre ellos. [ 59 ] [ 60 ]
El modelo más popular y desarrollado de POO es el basado en clases, en lugar del basado en objetos. En este modelo, los objetos son entidades que combinan estado (es decir, datos), comportamiento (es decir, procedimientos o métodos ) e identidad (existencia única entre todos los demás objetos). La estructura y el comportamiento de un objeto se definen mediante una clase , que es una estructura sintáctica , o plantilla , de todos los objetos de un tipo específico. Un objeto debe crearse explícitamente a partir de una clase, y un objeto así creado se considera una instancia de esa clase. Un objeto es similar a una estructura , con la adición de punteros a métodos, control de acceso a miembros y un miembro de datos implícito que localiza las instancias de la clase (es decir, los objetos de la clase) en la jerarquía de clases (esencial para las características de herencia en tiempo de ejecución).
Encapsulación
La encapsulación impide que los usuarios rompan las invariantes de la clase, lo cual es útil porque permite modificar la implementación de una clase de objetos para aspectos no expuestos en la interfaz sin afectar el código del usuario. Las definiciones de encapsulación se centran en la agrupación y el empaquetado de información relacionada ( cohesión ) más que en cuestiones de seguridad.
Crítica
Los lenguajes basados en clases, o, para ser más precisos, lenguajes tipados , donde la herencia es la única forma de subtipado , han sido criticados por mezclar implementaciones e interfaces , el principio esencial de la programación orientada a objetos. Los críticos dicen que se podría crear una clase `bag` que almacene una colección de objetos, y luego extenderla para crear una nueva clase llamada `set` donde se elimina la duplicación de objetos. [ 61 ] [ 62 ] Ahora bien, una función que recibe un objeto de la clase `bag` puede esperar que agregar dos objetos aumente el tamaño de una bolsa en dos, pero si se pasa un objeto de la clase `set`, agregar dos objetos puede o no aumentar el tamaño de una bolsa en dos. El problema surge precisamente porque la herencia implica subtipado incluso en los casos en que el principio de subtipado, conocido como principio de sustitución de Liskov , no se cumple. Barbara Liskov y Jeannette Wing formularon el principio sucintamente en un artículo de 1994 de la siguiente manera:
Requisito de subtipo : Let ser una propiedad demostrable sobre objetosde tipo . Entonces debería ser cierto para los objetos de tipo¿ Dónde ?es un subtipo de .
Por lo tanto, normalmente se debe distinguir entre subtipos y subclases. La mayoría de los lenguajes orientados a objetos actuales distinguen entre subtipos y subclases; sin embargo, algunos enfoques de diseño no lo hacen.
Otro ejemplo común es que un objeto de tipo persona creado a partir de una clase hija no puede convertirse en un objeto de la clase padre, ya que tanto la clase hija como la clase padre heredan de la clase persona. Sin embargo, los lenguajes basados en clases generalmente no permiten cambiar el tipo de clase del objeto en tiempo de ejecución. Para estos lenguajes, esta restricción es esencial para mantener una visión unificada de la clase para sus usuarios. Los usuarios no deberían preocuparse si alguna implementación de un método provoca cambios que alteren las invariantes de la clase. Dichos cambios se pueden realizar destruyendo el objeto y creando otro en su lugar. El polimorfismo permite preservar las interfaces relevantes incluso cuando se realizan estos cambios, ya que los objetos se consideran abstracciones de caja negra y se accede a ellos mediante su identidad . No obstante, normalmente se modifica el valor de las referencias a objetos, lo que afecta al código del cliente.
Idiomas de ejemplo
Aunque Simula introdujo la abstracción de clases, el ejemplo canónico de un lenguaje basado en clases es Smalltalk . Otros ejemplos son PHP , C++ , Java , C# y Objective-C .
Programación basada en prototipos
A diferencia de la creación de un objeto a partir de una clase, algunos contextos de programación admiten la creación de objetos mediante la copia (clonación) de un objeto prototipo . [ 63 ]
Véase también
- Bloque (programación) : grupo delimitado de instrucciones de código fuente que se ejecutan en secuencia.
- Diagrama de clases : diagrama que describe la estructura estática de un sistema de software.
- Invariante de clase : propiedad inmutable para todos los objetos de una clase.
- Variable de clase : variable definida en una clase cuyos objetos poseen todos la misma copia.
- Función (informática) : secuencia de instrucciones de un programa que puede ser invocada por otro software. Páginas que muestran breves descripciones de los destinos de redirección.
- Variable de instancia : variable miembro de una clase de la que todos sus objetos poseen su propia copia.
- Metaclase : clase que describe el comportamiento común para las clases.
- Objeto (informática) – Instancia semántica con estado, comportamiento e identidad.
- Sintaxis (lenguaje de programación) : forma del código fuente, sin tener en cuenta el significado. Páginas que muestran breves descripciones de los destinos de redirección.
- Variable (informática) : contenedor con nombre para un tipo de datos específico. Páginas que muestran descripciones breves de los destinos de redireccionamiento.
Notas
- 1 2 3 4 5 Dahl, Ole-Johan ; Myhrhaug, Bjørn; Nygaard, Kristen (1970). Lenguaje base común (PDF) (Reporte). Centro de Computación de Noruega. Archivado desde el original el 19 de septiembre de 2024 . Consultado el 20 de agosto de 2025 .
- ^ Gama y col. 1995 , pág. 14.
- ↑ Bruce 2002 , 2.1 Objetos, clases y tipos de objetos, https://books.google.com/books?id=9NGWq3K1RwUC&pg=PA18 .
- ^ Gama y col. 1995 , pág. 17.
- 1 2 "3. Modelo de datos" . The Python Language Reference . Python Software Foundation . Consultado el 26 de abril de 2012 .
- ↑ Booch 1994 , págs. 86-88.
- ↑ "Clases (I)" . Tutorial del lenguaje C++ . cplusplus.com . Consultado el 29 de abril de 2012 .
- ↑ "Clases (II)" . Tutorial del lenguaje C++ . cplusplus.com . Consultado el 29 de abril de 2012 .
- ↑ Booch 1994 , pág. 105.
- ↑ Parsons, June Jamrich (22 de junio de 2015). Nuevas perspectivas sobre conceptos informáticos 2016, edición integral . Boston, MA: Cengage Learning. ISBN 9781305271616OCLC 917155105
- 1 2 "Controlar el acceso a los miembros de una clase" . Los tutoriales de Java . Oracle . Consultado el 19 de abril de 2012 .
- ↑ "OOP08-CPP. No devolver referencias a datos privados" . Estándar de codificación segura CERT C++ . Universidad Carnegie Mellon. 10 de mayo de 2010. Archivado del original el 3 de octubre de 2015. Consultado el 7 de mayo de 2012 .
- ↑ Ben-Ari, Mordechai (24-01-2007). "2.2 Identificadores" (PDF) . Errores de compilación y de tiempo de ejecución en Java . Archivado (PDF) del original el 18-10-2011 . Recuperado el 07-05-2012 .
- 1 2 Wild, Fred. "Interfaces de C++" . Dr. Dobb's . UBM Techweb . Recuperado el 2 de mayo de 2012 .
- ↑ "modules_and_classes: Visibility" .
- ↑ "Amistad y herencia" . Tutorial del lenguaje C++ . cplusplus.com . Consultado el 26 de abril de 2012 .
- ↑ Berfeld, Marya (2 de diciembre de 2008). "Transformación de UML a Java en las ediciones de IBM Rational Software Architect y software relacionado" . IBM . Recuperado el 20 de diciembre de 2013 .
- ^ Jacobsen, Ivar; Magnus Christerson; Patrik Jonsson; Gunnar Overgaard (1992). Ingeniería de Software Orientada a Objetos . Prensa Addison-Wesley ACM. págs. 43–69 . ISBN 0-201-54435-0.
- ↑ Knublauch, Holger; Oberle, Daniel; Tetlow, Phil; Wallace, Evan (2006-03-09). "Una introducción a la web semántica para desarrolladores de software orientados a objetos" . W3C . Recuperado el 30 de julio de 2008 .
- ↑ Booch 1994 , pág. 180.
- ↑ Booch 1994 , págs. 128-129.
- ↑ Booch 1994 , pág. 112.
- 1 2 "Interfaces" . Los tutoriales de Java . Oracle . Consultado el 1 de mayo de 2012 .
- 1 2 Bell, Donald. "UML Basics: The class diagram" . developerWorks . IBM . Consultado el 2 de mayo de 2012 .
- ↑ Booch 1994 , pág. 179.
- 1 2 "Polimorfismo" . Tutorial del lenguaje C++ . cplusplus.com . Consultado el 2 de mayo de 2012 .
- ↑ "Métodos y clases abstractas" . Los tutoriales de Java . Oracle . Consultado el 2 de mayo de 2012 .
- ↑ "Abstracción de clases" . Manual de PHP . The PHP Group . Consultado el 2 de mayo de 2012 .
- ↑ "Interfaces (Guía de programación de C#)" . Guía de programación de C# . Microsoft . Consultado el 15 de agosto de 2013 .
- ↑ "Herencia (Guía de programación de C#)" . Guía de programación de C# . Microsoft . Consultado el 2 de mayo de 2012 .
- ↑ "Clases anidadas (solo C++)" . XL C/C++ V8.0 para AIX . IBM . Consultado el 7 de mayo de 2012 .
- ↑ "Nombres de tipos locales (solo C++)" . XL C/C++ V8.0 para AIX . IBM . Consultado el 7 de mayo de 2012 .
- ↑ "Clases locales (solo C++)" . XL C/C++ V8.0 para AIX . IBM . Consultado el 7 de mayo de 2012 .
- ↑ Booch 1994 , págs. 133-134.
- ↑ "13 Clases y metaclases" . pharo.gforge.inria.fr . Archivado del original el 24 de febrero de 2021. Consultado el 31 de octubre de 2016 .
- ↑ "clase Clase" .
- ↑ Booch 1994 , pág. 134.
- ↑ "MOP: Conceptos" . Protocolo MetaObject del Sistema de Objetos de Common Lisp . Asociación de Usuarios de Lisp. Archivado del original el 15/11/2010 . Consultado el 08/05/2012 .
- ↑ "sellado (Referencia de C#)" . Referencia de C# . Microsoft . Consultado el 8 de mayo de 2012 .
- ↑ "Escritura de clases y métodos finales" . Los tutoriales de Java . Oracle . Consultado el 8 de mayo de 2012 .
- ↑ "PHP: Palabra clave final" . Manual de PHP . The PHP Group . Consultado el 21 de agosto de 2014 .
- ↑ "Clases selladas" . Centro de ayuda de Oracle . Consultado el 7 de julio de 2025 .
- ↑ Personal (15 de diciembre de 2025). "Herencia" . Kotlinlang.org . JetBrains sro
- ↑ "String (Java Platform SE 7)" . Java Platform, Standard Edition 7: Especificación de API . Oracle . Consultado el 8 de mayo de 2012 .
- ↑ Brand, Sy (2 de marzo de 2020). "Los beneficios de rendimiento de las clases finales" . Blog del equipo de Microsoft C++ . Microsoft . Consultado el 4 de abril de 2020 .
- ↑ "Clases selladas" . docs.oracle.com . Centro de ayuda de Oracle . Consultado el 16 de octubre de 2025 .
- ↑ Oracle Corporation. "4 - Clases selladas" . docs.oracle.com . Oracle Corporation . Consultado el 7 de junio de 2026 .
- ↑ "9. Clases" . El tutorial de Python . Python.org . Consultado el 3 de marzo de 2018.
Al igual que los módulos, las clases participan de la naturaleza dinámica de Python: se crean en tiempo de ejecución y se pueden modificar posteriormente.
- 1 2 mairaw; BillWagner; tompratt-AQ (19 de septiembre de 2015), "Clases y métodos parciales" , Guía de programación de C# , Microsoft , consultado el 8 de agosto de 2018
- ↑ "Clases y miembros parciales - C#" .
- ↑ BillWagner (14 de noviembre de 2024). "Clases y métodos parciales - C#" . learn.microsoft.com . Consultado el 6 de febrero de 2025 .
- ↑ "Clases estáticas y miembros de clase estáticos (Guía de programación de C#)" . Guía de programación de C# . Microsoft . Consultado el 8 de mayo de 2012 .
- ↑ "Clases anónimas (Tutoriales de Java > Aprendiendo el lenguaje Java > Clases y objetos)" . docs.oracle.com . Consultado el 13 de mayo de 2021 .
- ↑ "PHP: Clases anónimas - Manual" . www.php.net . Consultado el 11 de agosto de 2021 .
- ↑ "¿Qué es un objeto?" . oracle.com . Oracle Corporation . Consultado el 13 de diciembre de 2013 .
- ↑Booch, Grady; Robert A. Maksimchuk; Michael W. Engle; Bobbi J. Young Ph.D.; Jim Conallen; Kelli A. Houston (April 30, 2007). Object-Oriented Analysis and Design with Applications. Addison-Wesley Professional. pp. 1–28. ISBN 978-0-201-89551-3. Retrieved 20 December 2013.
There are fundamental limiting factors of human cognition; we can address these constraints through the use of decomposition, abstraction, and hierarchy.
- ↑Jacobsen, Ivar; Magnus Christerson; Patrik Jonsson; Gunnar Overgaard (1992). Object Oriented Software Engineering. Addison-Wesley ACM Press. ISBN 0-201-54435-0.
- ↑"C++ International standard"(PDF). Working Draft, Standard for Programming Language C++. ISO/IEC JTC1/SC22 WG21. Archived(PDF) from the original on 2017-12-09. Retrieved 5 January 2020.
- ↑Wegner, Peter (1987). "Dimensions of object-based language design". Conference proceedings on Object-oriented programming systems, languages and applications. pp. 168–182. doi:10.1145/38765.38823. ISBN 0-89791-247-0.
- ↑Liskov, Barbara (1996). "A history of CLU". History of programming languages---II. pp. 471–510. doi:10.1145/234286.1057826. ISBN 0-201-89502-1.
- ↑Kiselyov, Oleg. "Subtyping, Subclassing, and Trouble with OOP". Retrieved 7 October 2012.
- ↑Ducasse, Stéphane. "A set cannot be a subtype of a bag". Retrieved 7 October 2012.
- ↑Amir, Masroor (25 March 2023). "OOP - Object Oriented Programming - Concepts | Languages | Benefits [2023]". The Geeks Bot: A Computer Science Site for geeks. Retrieved 2023-04-04.
References
- Booch, Grady (1994). Objects and Design with Applications, Second Edition. Benjamin/Cummings.
- Gamma; Helm; Johnson; Vlissides (1995). Design Patterns: Elements of Reusable Object-Oriented Software. Addison Wesley. ISBN 9780201633610.
- Bruce, Kim B. (2002). Foundations of Object-Oriented Languages: Types and Semantics. Cambridge, Massachusetts: MIT Press. ISBN 978-0-262-02523-2.
Further reading
- Abadi; Cardelli: Una teoría de los objetos
- ISO/IEC 14882:2003 Lenguaje de programación C++, estándar internacional
- Guerra de clases: Clases vs. Prototipos , por Brian Foote
- Meyer, B.: "Construcción de software orientado a objetos", 2.ª edición, Prentice Hall, 1997, ISBN 0-13-629155-4
- Rumbaugh et al.: "Modelado y diseño orientado a objetos", Prentice Hall, 1991, ISBN 0-13-630054-5
- Clase (programación informática)
- Estructuras de programación
- Temas de lenguajes de programación