Clase (programación informática)
En la programación orientada a objetos, una clase es una plantilla de código de programa extensible para crear objetos, proporcionando valores iniciales para el estado (variables miembro) e implementaciones de comportamiento (funciones miembro o métodos). En muchos idiomas, el nombre de la clase se usa como el nombre de la clase (la plantilla en sí), el nombre del constructor predeterminado de la clase (una subrutina que crea objetos) y como el tipo de objetos generados al instanciar la clase; estos conceptos distintos se combinan fácilmente. Aunque, hasta el punto de la confusión, se podría argumentar que es una característica inherente a un lenguaje debido a su naturaleza polimórfica y por qué estos lenguajes son tan poderosos, dinámicos y adaptables para su uso en comparación con los lenguajes sin polimorfismo presente. Por lo tanto, pueden modelar sistemas dinámicos (es decir, el mundo real, el aprendizaje automático, la IA) más fácilmente.
Cuando un constructor de la clase crea un objeto, el objeto resultante se denomina instancia de la clase y las variables miembro específicas del objeto se denominan variables de instancia, en contraste con las variables de clase compartidas en la clase.
En ciertos lenguajes, las clases son, de hecho, solo una función en tiempo de compilación (las nuevas clases no se pueden declarar en tiempo de ejecución), mientras que en otros lenguajes las clases son ciudadanos de primera clase y, por lo general, son objetos en sí mismas. (típicamente de tipo Class o similar). En estos lenguajes, una clase que crea clases dentro de sí misma se denomina metaclase.
Clase frente a tipo
En su uso más informal, las personas a menudo se refieren a la "clase" de un objeto, pero estrictamente hablando, los objetos tienen tipo: la interfaz, es decir, los tipos de variables miembro, las firmas de las funciones miembro (métodos) y las propiedades que estas satisfacen. Al mismo tiempo, una clase tiene una implementación (específicamente la implementación de los métodos), y puede crear objetos de un tipo dado, con una implementación dada. En los términos de la teoría de tipos, una clase es una implementación—una estructura 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 Stack podría implementarse con dos clases: SmallStack (rápido para pilas pequeñas, pero se escala mal) y < span class="monospaced">ScalableStack (se escala bien pero tiene una sobrecarga alta para pilas pequeñas). De manera similar, una clase dada puede tener varios constructores diferentes.
Los tipos de clase generalmente representan sustantivos, como una persona, un lugar o una cosa, o algo nominalizado, y una clase representa una implementación de estos. Por ejemplo, un tipo Banana podría representar las propiedades y la funcionalidad de los plátanos en general, mientras que ABCBanana y XYZBanana representarían formas de producir plátanos (por ejemplo, proveedores de plátanos o estructuras de datos y funciones para representar y dibujar plátanos en un videojuego). La clase ABCBanana podría producir plátanos particulares: las instancias de la clase ABCBanana serían objetos de tipo Plátano. A menudo, solo se proporciona una única implementación de un tipo, en cuyo caso el nombre de la clase suele ser idéntico al nombre del tipo.
Diseño e implementación
Las clases se componen de componentes estructurales y de comportamiento. Los lenguajes de programación que incluyen clases como una construcción de programación ofrecen soporte para varias funciones relacionadas con clases, y la sintaxis requerida para usar estas funciones varía mucho de un lenguaje de programación a otro.
Estructura
Una clase contiene descripciones de campos de datos (o propiedades, campos, miembros de datos o atributos). Por lo general, estos son tipos de campo y nombres que se asociarán con variables de estado en el tiempo de ejecución del programa; estas variables de estado pertenecen a la clase oa instancias específicas de la clase. En la mayoría de los lenguajes, la estructura definida por la clase determina el diseño de la memoria utilizada por sus instancias. Son posibles otras implementaciones: por ejemplo, los objetos en Python usan contenedores asociativos de clave-valor.
Algunos lenguajes de programación, como Eiffel, admiten la especificación de invariantes como parte de la definición de la clase y las imponen a través del sistema de tipos. La encapsulación del estado es necesaria para poder hacer cumplir las invariantes de la clase.
Comportamiento
El comportamiento de la 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. Existen muchos tipos de métodos, pero el soporte para ellos varía según los idiomas. 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 que el programador defina y llame a estos métodos especiales.
El concepto de interfaz de clase
Cada clase implementa (o realiza) una interfaz proporcionando 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. Hay una distinción entre la definición de una interfaz y la implementación de esa interfaz; sin embargo, esta línea está borrosa en muchos lenguajes de programación porque las declaraciones de clase definen e implementan una interfaz. Sin embargo, algunos lenguajes proporcionan características que separan la interfaz y la implementación. Por ejemplo, una clase abstracta puede definir una interfaz sin proporcionar implementación.
Los lenguajes que admiten la herencia de clases también permiten que las clases hereden interfaces de las clases de las que se derivan.
Por ejemplo, si "clase A" hereda de la "clase B" y si "clase B" implementa la interfaz "interfaz B" luego "clase A" también hereda la funcionalidad (constantes y declaración de métodos) proporcionada por la "interfaz B".
En lenguajes que soportan especificadores de acceso, la interfaz de una clase se considera como el conjunto de miembros públicos de la clase, incluyendo tanto métodos como atributos (a través de métodos implícitos getter y setter); los miembros privados o las estructuras de datos internas no están destinados a depender de un código externo y, por lo tanto, no forman parte de la interfaz.
La metodología de programación orientada a objetos dicta que las operaciones de cualquier interfaz de una clase deben ser independientes entre sí. Da como resultado un diseño en capas donde los clientes de una interfaz usan los métodos declarados en la interfaz. Una interfaz no impone requisitos para que los clientes invoquen las operaciones de una interfaz en un orden particular. Este enfoque tiene la ventaja de que el código del cliente puede asumir que las operaciones de una interfaz están disponibles para su uso siempre que el cliente tenga acceso al objeto.
Ejemplo
Los botones en la parte frontal de su televisor son la interfaz entre usted y el cableado eléctrico al otro lado de su carcasa de plástico. Presionas el botón "power" botón para encender y apagar la televisión. En este ejemplo, su televisor particular es la instancia, cada método está representado por un botón, y todos los botones juntos componen la interfaz (otros televisores que son del mismo modelo que el suyo tendrían la misma interfaz). En su forma más común, una interfaz es una especificación de un grupo de métodos relacionados sin ninguna implementación asociada de los métodos.
Un televisor también tiene una miríada de atributos, como el tamaño y la compatibilidad con el color, que en conjunto conforman su estructura. Una clase representa la descripción completa de un televisor, incluidos 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 de televisores. Este método está claramente asociado con la clase, pero está fuera del dominio de cada instancia individual de la clase. Un método estático que encuentra una instancia particular fuera del conjunto de todos los objetos de televisión es otro ejemplo.
Accesibilidad de miembros
El siguiente es un conjunto común de especificadores de acceso:
- Privado (o clase-privada) restringe el acceso a la clase misma. Sólo los métodos que forman parte de la misma clase pueden acceder a miembros privados.
- Protegido (o protección de clases) permite que la clase misma y todas sus subclases accedan al miembro.
- Público significa que cualquier código puede acceder al miembro por su nombre.
Aunque muchos lenguajes orientados a objetos admiten los especificadores de acceso anteriores, su semántica puede diferir.
El diseño orientado a objetos utiliza los especificadores de acceso junto con un diseño cuidadoso de implementaciones de métodos públicos para imponer invariantes de clase: restricciones en 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úblico se pueden usar para inspeccionar o modificar dichos datos privados.
Los especificadores de acceso no controlan necesariamente 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 de miembro), pero un intento de usarlo haciendo referencia al nombre del miembro del código del cliente se verá frustrado. impedido por el verificador de tipos.
Los diversos lenguajes de programación orientados a objetos imponen la accesibilidad y la visibilidad de los miembros en varios grados y, según el sistema de tipo del lenguaje y las políticas de compilación, se aplican en tiempo de compilación o en tiempo de ejecución. Por ejemplo, el lenguaje Java no permite compilar el código de cliente que accede a los datos privados de una clase. 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 representan las interfaces de la clase.
Algunos idiomas presentan otros esquemas de accesibilidad:
- Instance vs. class accessibility: Ruby apoya instancias privadas y protección de casos acceso a los especificadores en lugar de clase-privada y de clase, respectivamente. Ellos difieren en que restringen el acceso basado en la instancia misma, en lugar de la clase de la instancia.
- Amigo: C++ apoya un mecanismo donde una función explícitamente declarada como una función amiga de la clase puede acceder a los miembros designados como privados o protegidos.
- Base de caminos: Java soporta 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 ampliar un marco Java para implementar clases en el mismo paquete que una clase marco para acceder a los miembros protegidos. El archivo fuente puede existir en un lugar completamente diferente, y puede ser desplegado en otro. tar file, sin embargo todavía estar en la misma ruta lógica en lo que respecta al JVM.
Relaciones entre clases
Además del diseño de clases independientes, los lenguajes de programación pueden admitir un diseño de clases más avanzado basado en las relaciones entre clases. Las capacidades de diseño de relaciones entre clases comúnmente proporcionadas son compositivas y jerárquicas.
Composicional
Las clases pueden estar compuestas por otras clases, estableciendo así una relación de composición entre la clase envolvente y sus clases incrustadas. La relación de composición entre clases también se conoce comúnmente como relación has-a. Por ejemplo, una clase "Coche" podría estar compuesto y contener una clase "Motor". Por lo tanto, un Automóvil tiene un Motor. Un aspecto de la composición es la contención, que es el encierro de instancias de componentes por parte de la instancia que las tiene. Si un objeto envolvente contiene instancias de componentes por valor, los componentes y su objeto envolvente tienen una vigencia similar. Si los componentes se incluyen por referencia, es posible que no tengan una vida útil similar. Por ejemplo, en Objective-C 2.0:
@interface Car: NSObject@property NSString *Nombre;@property Motor *motor@property NSArray *neumáticos;@end
Esta clase Coche tiene una instancia de NSString (un objeto de cadena), Engine y NSArray (un objeto de matriz).
Jerárquica
(feminine)Las clases se pueden derivar de una o más clases existentes, estableciendo así una relación jerárquica entre las clases derivadas (clases base, clases padre i> o superclases< /span>) y la clase derivada (clase secundaria o subclase). La relación de la clase derivada con las clases derivadas se conoce comúnmente como relación es-un. Por ejemplo, una clase 'Botón' podría derivarse de una clase 'Control'. Por lo tanto, un Botón es un Control. Los miembros estructurales y de comportamiento de las clases principales son heredados por la clase secundaria. Las clases derivadas pueden definir miembros estructurales adicionales (campos de datos) y miembros de comportamiento (métodos) además de los que heredan y, por lo tanto, son especializaciones de sus superclases. Además, las clases derivadas pueden anular los métodos heredados si el lenguaje lo permite.
No todos los idiomas admiten la herencia múltiple. Por ejemplo, Java permite que una clase implemente múltiples interfaces, pero solo herede de una clase. Si se permite la herencia múltiple, la jerarquía es un gráfico acíclico dirigido (o DAG para abreviar); de lo contrario, es un árbol. La jerarquía tiene clases como nodos y relaciones de herencia como enlaces. Las clases en el mismo nivel tienen más probabilidades de estar asociadas que las clases en diferentes niveles. Los niveles de esta jerarquía se denominan capas o niveles de abstracción.
Ejemplo (código de Objective-C 2.0 simplificado, del iPhone SDK):
@interface UIResponder: NSObject //...@interface UIView: UIResponder //...@interface UIScroll Ver: UIView //...@interface UITableView: UIScroll Ver //...
En este ejemplo, UITableView es un UIScrollView es un UIView es un UIResponder es un NSObject.
Definiciones de subclase
Conceptualmente, una superclase es un superconjunto de sus subclases. Por ejemplo, una jerarquía de clases común implicaría GraphicObject como una superclase de Rectangle y Elipse< /span>, mientras que Cuadrado sería una subclase de Rectangle. Estas también son relaciones de subconjuntos 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 es confundir una relación parte de con una subclase. Por ejemplo, un automóvil y un camión son tipos de vehículos y sería apropiado modelarlos como subclases de una clase de vehículos. Sin embargo, sería un error modelar las partes componentes del automóvil como relaciones de subclase. Por ejemplo, un automóvil se compone de un motor y una carrocería, pero no sería apropiado modelar el motor o la carrocería como una subclase de automóvil.
En el modelado orientado a objetos, este tipo de relaciones normalmente se modelan como propiedades de objetos. En este ejemplo, la clase Car tendría una propiedad llamada parts. Se escribirían parts para contener una colección de objetos, como instancias de Body, Engine , Neumáticos, etc. Los lenguajes de modelado de objetos como UML incluyen capacidades para modelar varios aspectos de "parte de" y otros tipos de relaciones: datos como la cardinalidad de los objetos, restricciones en los valores de entrada y salida, etc. Las herramientas de desarrollo pueden utilizar esta información para generar código adicional además de las definiciones de datos básicos para los objetos, como la verificación de errores en obtener y establecer métodos.
Una pregunta 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 intersectaran con más de otro conjunto. Sin embargo, mientras que algunos sistemas como Flavors y CLOS brindan la capacidad para que más de un padre lo haga en tiempo de ejecución, presenta una complejidad que muchos en la comunidad orientada a objetos consideran antitética para los objetivos de usar clases de objetos en primer lugar. Comprender qué clase será responsable de manejar un mensaje puede volverse complejo cuando se trata de más de una superclase. Si se usa sin cuidado, esta función puede introducir parte de la misma complejidad del sistema y las clases de ambigüedad que se diseñaron para evitar.
La mayoría de los lenguajes orientados a objetos modernos, como Smalltalk y Java, requieren herencia única 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 aplicaciones web semánticas tienen varias superclases. La volatilidad de Internet requiere este nivel de flexibilidad y los estándares tecnológicos como Web Ontology Language (OWL) están diseñados para soportarlo.
Un problema similar es si la jerarquía de clases se puede modificar o no en tiempo de ejecución. Los lenguajes como Flavors, CLOS y Smalltalk admiten esta función como parte de sus protocolos de metaobjetos. Dado que las clases son en sí mismas objetos de primera clase, es posible hacer que alteren dinámicamente su estructura enviándoles los mensajes apropiados. Otros lenguajes que se centran más en la tipificación 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 el tiempo de ejecución de las clases. Lo racional es similar a la justificación para permitir múltiples superclases, que Internet es tan dinámico y flexible que se requieren cambios dinámicos en la jerarquía para manejar esta volatilidad.
Ortogonalidad del concepto de clase y herencia
Aunque comúnmente se asume que los lenguajes basados en clases soportan la herencia, la herencia no es un aspecto intrínseco del concepto de clases. Algunos lenguajes, a menudo denominados "lenguajes basados en objetos", admiten clases pero no admiten la herencia. Los ejemplos de lenguajes basados en objetos incluyen versiones anteriores de Visual Basic.
Dentro del análisis orientado a objetos
En el análisis orientado a objetos y en 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. Las asociaciones pueden etiquetarse de acuerdo con su nombre o propósito.
Un rol de asociación se da al final de una asociación y describe el rol de la clase correspondiente. Por ejemplo, un "suscriptor" rol describe la forma en que las instancias de la clase "Persona" participar en un "suscribirse a" asociación con la clase "Revista". Además, una "Revista" tiene la "revista suscrita" puesto en la misma asociación. La multiplicidad de roles 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 "*" especifica cualquier número de instancias.
Taxonomía de clases
Hay muchas categorías de clases, algunas de las cuales se superponen.
Abstracta y concreta
(feminine)En un lenguaje que soporta herencia, una clase abstracta, o clase base abstracta (ABC), es una clase que no puede ser instanciada porque está etiquetada como abstracta o simplemente especifica métodos abstractos (o métodos virtuales). Una clase abstracta puede proporcionar implementaciones de algunos métodos y también puede especificar métodos virtuales a través de firmas que deben implementar los descendientes directos o indirectos de la clase abstracta. Antes de que se pueda instanciar una clase derivada de una clase abstracta, alguna clase en la cadena de derivación debe implementar todos los métodos abstractos de sus clases principales.
La mayoría de los lenguajes de programación orientados a objetos permiten que el programador especifique qué clases se consideran abstractas y no permitirán que se instancian. Por ejemplo, en Java, C# y PHP, se utiliza la palabra clave abstract. 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 el lenguaje de C++).
Una clase que consta únicamente de métodos virtuales se denomina clase base abstracta pura (o ABC puro) en C++ y también se conoce como interfaz por los usuarios del lenguaje.. Otros lenguajes, en particular Java y C#, admiten una variante de clases abstractas denominada interfaz a través de una palabra clave en el lenguaje. En estos lenguajes, la herencia múltiple no está permitida, pero una clase puede implementar múltiples interfaces. Tal clase solo puede contener métodos abstractos de acceso público.
Una clase concreta es una clase que puede instanciarse, a diferencia de las clases abstractas, que no pueden.
Local e interior
En algunos lenguajes, las clases se pueden declarar en ámbitos distintos al ámbito global. Hay varios tipos de tales 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 clase. Por lo general, una clase interna no está asociada con instancias de la clase envolvente ni se instancia junto con su clase envolvente. Dependiendo del idioma, puede o no ser posible referirse a la clase desde fuera de la clase adjunta. Un concepto relacionado es tipos internos, también conocido como tipo de datos internos o tipo anidado, que es una generalización del concepto de clases internas. C++ es un ejemplo de un lenguaje que admite tanto clases internas como tipos internos (a través de declaraciones typedef).
Otro tipo es una clase local, que es una clase definida dentro de un procedimiento o función. Esto limita las referencias al nombre de la clase dentro del ámbito donde se declara la clase. Dependiendo de las reglas semánticas del idioma, puede haber restricciones adicionales en las clases locales en comparación con las no locales. Una restricción común es no permitir que los métodos de clase local accedan a las variables locales de la función envolvente. Por ejemplo, en C++, una clase local puede hacer referencia a variables estáticas declaradas dentro de su función envolvente, pero no puede acceder a las variables automáticas de la función.
Metaclases
Las metaclases son clases cuyas instancias son clases. 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.
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. El Common Lisp Object System (CLOS) proporciona protocolos de metaobjetos (MOP) para implementar esas clases y metaclases.
No subclasificable
Las clases no subclasificables permiten a los programadores diseñar clases y jerarquías de clases en las que, en algún nivel de la jerarquía, está prohibida la derivación adicional (una clase independiente también puede designarse como no subclasificable, lo que impide la formación de cualquier jerarquía). Contraste esto con las clases abstractas, que implican, fomentan y requieren derivación para poder usarse. Una clase no subclasificable es implícitamente concreta.
Una clase no subclasificable se crea declarando la clase como sellado
en C# o como final
en Java o PHP. Por ejemplo, Java's String code> se designa como final.
Las clases no subclasificables pueden permitir que un compilador (en lenguajes compilados) realice optimizaciones que no están disponibles para las clases subclasificables.
Clase abierta
Una clase abierta es aquella que se puede cambiar. Por lo general, los clientes no pueden cambiar un programa ejecutable. Los desarrolladores a menudo pueden cambiar algunas clases, pero normalmente no pueden cambiar las estándar o integradas. En Ruby, todas las clases están abiertas. En Python, las clases se pueden crear en tiempo de ejecución y todas se pueden modificar después. Las categorías de Objective-C permiten al programador agregar métodos a una clase existente sin la necesidad de volver a compilar esa clase o incluso tener acceso a su código fuente.
Mezclas
Algunos lenguajes tienen soporte especial para mixins, aunque en cualquier lenguaje con herencia múltiple, un mixin es simplemente una clase que no representa una relación is-a-type-of. Los mixins generalmente se usan para agregar los mismos métodos a varias clases; por ejemplo, una clase UnicodeConversionMixin podría proporcionar un método llamado unicode_to_ascii cuando se incluye en las clases FileReader< /span> y WebPageScraper que no comparten un padre común.
Parcial
En los idiomas que admiten la función, una clase parcial es una clase cuya definición se puede dividir en varias partes, dentro de un solo archivo de código fuente o en varios archivos. Las piezas 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 motivación principal para la introducción de clases parciales es facilitar la implementación de generadores de código, como diseñadores visuales. De lo contrario, es un desafío o compromiso desarrollar generadores de código que puedan administrar el código generado cuando se intercala dentro del código escrito por el desarrollador. Al usar clases parciales, un generador de código puede procesar un archivo separado o una clase parcial de granularidad gruesa dentro de un archivo y, por lo tanto, se libera de la intrincada interposición del código generado a través de un análisis exhaustivo, lo que aumenta la eficiencia del compilador y elimina 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. Entonces, la compilación puede continuar como de costumbre.
Otros beneficios y efectos de la característica de clase parcial incluyen:
- Permite la separación de la interfaz de una clase y el código de implementación de una manera única.
- Eases navigation through large classes within an editor.
- Permite la separación de preocupaciones, de una manera similar a la programación orientada hacia aspectos, pero sin utilizar herramientas adicionales.
- Permite a múltiples desarrolladores trabajar en una sola clase simultáneamente sin la necesidad de combinar el código individual en un archivo más adelante.
Las clases parciales han existido en Smalltalk bajo el nombre de Extensiones de clase durante un tiempo considerable. Con la llegada de.NET Framework 2, Microsoft introdujo clases parciales, compatibles con C# 2.0 y Visual Basic 2005. WinRT también admite clases parciales.
Ejemplo en VB.NET
Este sencillo ejemplo, escrito en Visual Basic.NET, muestra cómo se definen partes de la misma clase en dos archivos diferentes.
- file1.vb
Parcial Clase MyClass Privado _name As StringFinal Clase
- file2.vb
Parcial Clase MyClass Público Readonly Propiedad Nombre() As String Vamos. Regreso _name Final Vamos. Final PropiedadFinal Clase
Cuando se compila, el resultado es el mismo que si los dos archivos se escribieran como uno solo, así:
Clase MyClass Privado _name As String Público Readonly Propiedad Nombre() As String Vamos. Regreso _name Final Vamos. Final PropiedadFinal Clase
Ejemplo en Objective-C
En Objective-C, las clases parciales, también conocidas como categorías, pueden incluso distribuirse en múltiples bibliotecas y ejecutables, como en el siguiente ejemplo. Pero una diferencia clave es que las categorías de Objective-C pueden sobrescribir definiciones en otra declaración de interfaz, y que las categorías no son iguales a la definición de clase original (la primera requiere la última). En cambio, la clase parcial de.NET no puede tener definiciones en conflicto y todas las definiciones parciales son iguales a las demás.
En Foundation, archivo de encabezado NSData.h:
@interface NSData: NSObject- ()id)initContentsOfURL:()NSURL *)URL;//...@end
En la biblioteca proporcionada por el usuario, un binario separado del marco de Foundation, archivo de encabezado NSData+base64.h:
#importar #Fundación/Fundación.h]@interface NSData (base64)- ()NSString *)base64String;- ()id)initWithBase64String:()NSString *)base64String;@end
Y en una aplicación, otro archivo binario separado, el archivo de código fuente main.m:
#importar #Fundación/Fundación.h]#import "NSData+base64.h"int principal()int argc, char *argv[]){} si ()argc . 2) retorno EXIT_FAILURE; NSString *sourceURLString = [NSString cuerda WithCString:argv[1]] NSData *datos = [[2]NSData alloc] initContentsOfURL:[NSURL URLWithString:sourceURLString]] NSLog()@"%@", [datos base64String]); retorno EXIT_SUCCESS;}
El despachador encontrará ambos métodos llamados a través de la instancia de NSData y los invocará a ambos correctamente.
No verificable
Lasclases no instanciables permiten a los programadores agrupar campos y métodos por clase a los que se puede acceder en tiempo de ejecución sin una instancia de la clase. De hecho, la creación de instancias está prohibida para este tipo de clase.
Por ejemplo, en C#, una clase marcada como "estática" no se puede crear una instancia, solo puede tener miembros estáticos (campos, métodos, otros), no puede tener constructores de instancias y está sellado.
Sin nombre
Una clase sin nombre o clase anónima es una clase que no está vinculada a un nombre o identificador en la definición. Esto es análogo a las funciones con nombre frente a las funciones sin nombre.
Beneficios
Los beneficios de organizar el software en clases de objetos se dividen en tres categorías:
- 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 hablar tanto con los desarrolladores como con los usuarios usando esencialmente el mismo vocabulario, hablando de cuentas, clientes, facturas, etc. Las clases de objetos a menudo facilitan el desarrollo rápido porque la mayoría de los entornos orientados a objetos vienen con poderosas herramientas de depuración y prueba. Las instancias de las clases se pueden inspeccionar en tiempo de ejecución para verificar que el sistema funciona según lo esperado. Además, en lugar de obtener volcados de la memoria central, la mayoría de los entornos orientados a objetos han interpretado las capacidades de depuración para que el desarrollador pueda analizar exactamente en qué lugar del programa ocurrió el error y pueda ver qué métodos fueron llamados a qué argumentos y con qué argumentos.
Las clases de objetos facilitan el mantenimiento a través de la encapsulación. Cuando los desarrolladores necesitan cambiar el comportamiento de un objeto, pueden localizar el cambio solo en ese objeto y sus componentes. Esto reduce el potencial de efectos secundarios no deseados de las mejoras de mantenimiento.
La reutilización de software también es una gran ventaja de usar clases de objetos. Las clases facilitan la reutilización a través de la herencia y las interfaces. Cuando se requiere un nuevo comportamiento, a menudo se puede lograr creando una nueva clase y haciendo que esa clase herede los comportamientos y datos predeterminados de su superclase y luego adapte algún aspecto del comportamiento o los datos en consecuencia. La reutilización a través de interfaces (también conocidas como métodos) ocurre cuando otro objeto quiere 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 aparecer en el software cuando un programa reutiliza el código de otro.
Representación en tiempo de ejecución
Como tipo de datos, una clase generalmente se considera como una construcción en tiempo de compilación. Un lenguaje o biblioteca también puede admitir prototipos o metaobjetos de fábrica que representan información en tiempo de ejecución sobre clases, o incluso representar metadatos que brindan acceso a las funciones de 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 tiempo de ejecución sobre clases de una clase sobre la base de que la información no es necesaria en tiempo de ejecución. Algunos lenguajes dinámicos no hacen distinciones estrictas entre las construcciones en tiempo de ejecución y en tiempo de compilación y, por lo tanto, es posible que no distingan entre metaobjetos y clases.
Por ejemplo, si Humano es un metaobjeto que representa la clase Persona, entonces se pueden crear instancias de la clase Persona usando las funciones del metaobjeto Humano.
Contenido relacionado
Cobertura de código
Operador bastardo del infierno
Navegador