Introspección de tipos

Introspección de tipos

En informática, la introspección de tipos es la capacidad de algunos lenguaje de programación orientado a objetos de determinar el tipo de un objeto en tiempo de ejecución. Esta es una característica notable de Objective-C, y una característica común en todo lenguaje que permita que clases de objetos sean manipuladas como objetos de clase primera por el programador. La introspección de tipos puede ser utilizada para implementar polimorfismo.

Contenido

Ejemplos

Ruby

La introspección de tipos es una característica básica de Ruby. En Ruby, la clase Object (padre de toda clase) incluye los métodos Object#instance_of? y Object#kind_of? para comprobar la clase de cualquier instancia. La última devuelve true cuando la instancia particular a la que se le envió el mensaje era una instancia de un descendiente de esta clase en cuestión. Para clarificar, considérese seguir el siguiente código de ejemplo (que puede probarse inmediatamente con irb):

$ irb
 
irb(main):001:0> A=Class.new
 
=> A
 
irb(main):002:0> B=Class.new A
 
=> B
 
irb(main):003:0> a=A.new
 
=> #<A:0x2e44b78>
 
irb(main):004:0> b=B.send 'new'
 
=> #<B:0x2e431b0>
 
irb(main):005:0> a.instance_of? A
 
=> true
 
irb(main):006:0> b.instance_of? A
 
=> false
 
irb(main):007:0> b.kind_of? A
 
=> true

En el ejemplo anterior, la clase Class se usa como cualquier otra clase en Ruby. Se crean dos clases, A y B, siendo la primera padre de la segunda, y luego se comprueba una instancia de cada clase. La última expresión nos devuelve verdadero porque A es una superclase de la clase de b. En el ejemplo inferior se muestra un método alternativo en Ruby que puede utilizarse para definir clases (y que lleva a un resultado idéntico):

$ irb
 
irb(main):001:0> class A; end
 
=> nil
 
irb(main):002:0> class B < A; end
 
=> nil
 
irb(main):003:0> a=A.new
 
=> #<A:0x2e4c33c>
 
irb(main):004:0> b=B.new
 
=> #<B:0x2e4a974>
 
irb(main):005:0> a.instance_of? A
 
=> true
 
irb(main):006:0> b.instance_of? A
 
=> false
 
irb(main):007:0> b.kind_of? A
 
=> true

También se puede preguntar directamente por la clase de cualquier objeto, y "compararlos" (el siguiente código asume haber ejecutado el código superior):

irb(main):008:0> A.instance_of? Class
 
=> true
 
irb(main):009:0> a.class
 
=> A
 
irb(main):010:0> a.class.class
 
=> Class
 
irb(main):011:0> A > B
 
=> true
 
irb(main):012:0> B <= A
 
=> true

Objective-C

En Objective-C, por ejemplo, ambos objetos genéricos Object y NSObject (en Cocoa/OpenStep) proporcionan el método isMemberOfClass: que devuelve true si el argumento al método es una instancia de la clase especificada. El método isKindOfClass: devuelve true si el argumento, de forma análoga, es descendiente de la clase especificada.

Por ejemplo, digamos que tenemos un par de clases Perrito y Gatito descendientes de una clase Animal, y una clase Veterinario.

Ahora, en el método desex puede escribirse

- desex: (id) to_desex
 
{
 
   if([to_desex isKindOfClass:[Animal class]])
 
   {
 
      //we're actually desexing an Animal, so continue
 
      if([to_desex isMemberOfClass:[Perrito class]])
 
         desex_dog(to_desex);
 
      else if([to_desex isMemberOfClass:[Gatito class]])
 
         desex_cat(to_desex);
 
      else
 
         error();
 
   }
 
   else
 
   {
 
      error();
 
   }
 
}

Ahora, cuando se llama a desex con un objeto genérico (un id), la función se comportará de forma correcta dependiendo del tipo de objeto genérico.

C++

C++ soporta introspección de tipos a través de las palabras clave typeid y dynamic cast.

La expresión dynamic_cast puede utilizarse para determinar si un objeto en concreto es de una clase determinada. Por ejemplo:

if(Persona *p = dynamic_cast<Persona *>(obj)){
 
  p->andar();
 
}

El operador typeid devuelve un objeto std::type_info que describe el tipo más derivado de un objeto:

std::cout << typeid(obj).name() << std::endl;

Object Pascal

La introspección de tipos ha sido parte de Object Pascal desde la primera versión de Delphi, que usa mucho RTTI para diseño visual de formularios. En Object Pascal, toda clase desciende de la clase base TObject, que implementa funcionalidad RTTI básica. El nombre de cada clase puede refrenciarse en código para propósitos de RTTI; el identificador del nombre de clase está implementado como un puntero a los metadatos de la clase, que pueden ser declarados y usados como una variable de tipo TClass.

El lenguaje include un operador is, para determinar si un objeto es o desciende de una clase determinada, así como un operador as, que proporciona typecast con comprobación de tipos, y varios métodos en TObject.

procedure Form1.MyButtonOnClick(Sender: TObject);
 
var
 
   aButton: TButton;
 
   SenderClass: TClass;
 
begin
 
   SenderClass := Sender.ClassType; //returns Sender's class pointer
 
   if sender is TButton then
 
   begin
 
      aButton := sender as TButton;
 
      EditBox.Text := aButton.Caption; //Property that the button has but generic objects don't
 
   end
 
   else begin
 
      EditBox.Text := Sender.ClassName; //returns the name of Sender's class as a string
 
   end;
 
end;

Introspección de Objetos Java

El ejemplo más sencillo de introspección de tipos en Java es el operador instanceof . El operador instanceof determina si un objeto concreto pertenece a una clase en particular (o a una subclase de esta, o a una clase que implemente tal interfaz). Por ejemplo:

if(obj instanceof Persona){
 
   Persona p = (Persona)obj;
 
   p.andar();
 
}

La clase java.lang.Class[1] es la base de una introspeción más avanzada.

Como ejemplo, si se desea determinar la clase actual de un objeto (más que si un objeto pertenece a una clase en concreto), pueden utilizarse los métodos Object.getClass() y Class.getName():

System.out.println(obj.getClass().getName());

Perl

Se puede lograr introspección con las funciones ref e isa Perl.

Podemos realizar introspección sobre las clases siguientes y sus instancias correspondientes:

package Animal;
 
sub new {
 
    my $class = shift;
 
    return bless {}, $class;
 
}
 
package Dog;
 
use base 'Animal';
 
package main;
 
my $animal = Animal->new();
 
my $dog = Dog->new();

utilizando:

print "This is an Animal.\n" if ref $animal eq 'Animal';
 
print "Dog is an Animal.\n" if $dog->isa('Animal');

Meta-Object Protocol (MOP)

Se puede lograr una introspección mucho mayor en Perl utilizando el sistema de objetos Moose[2] y la Class::MOP protocolo meta-object,[3] por ejemplo de esta forma se puede comprobar si un objeto determinado realiza un rol X:

if ($object->meta->does_role("X")) {
 
    # do something ...
 
}

Se puede listar como sigue una lista de los nombres completamente cualificados de todos los métodos que pueden ser invocados en el objeto, junto con las clases en donde fueron definidos::

for my $method ($object->meta->get_all_methods) {
 
    print $method->fully_qualified_name, "\n";
 
}

Véase también

Referencias

  1. Java API: java.lang.Class
  2. Moose meta API documentation (en inglés)
  3. Class::MOP - a meta-object protocol for Perl (en inglés)

Enlaces externos


Wikimedia foundation. 2010.

Игры ⚽ Нужно решить контрольную?

Mira otros diccionarios:

  • Historia del arte — Para la historiografía de la historia del arte, véase Estudio de la historia del arte. La creación …   Wikipedia Español

  • Tcl — Tool Command Language Desarrollador(es) Tcl Core Team[1] …   Wikipedia Español

  • Historia del desnudo artístico — David (1501 1504), de Miguel Ángel, Galería de la Academia de Florencia. La evolución histórica del desnudo artístico ha corrido en paralelo a la historia del arte en general, salvo pequeñas particularidades derivadas de la distinta aceptación de …   Wikipedia Español

  • Historia de la psicología — Psicología. Contenido 1 La Psicología como parte de la Filosofía 2 Empirismo y …   Wikipedia Español

  • Emoción — Saltar a navegación, búsqueda Las emociones son fenómenos psicofisiológicos que representan modos eficaces de adaptación a ciertos cambios de las demandas ambientales. Psicológicamente, las emociones alteran la atención, hacen subir de rango… …   Wikipedia Español

  • Ruby — Este artículo trata sobre el lenguaje de programación. Para la notación de ayuda a la lectura, véase Carácter ruby. Ruby Desarrollador(es) Comunidad de desarrolladores de Ru …   Wikipedia Español

  • Ser de España — El Ser de España o el Problema de España es el nombre que suele designar[1] un debate intelectual acerca de la identidad nacional española que surge con el regeneracionismo a finales del siglo XIX, y coincidiendo con el surgimiento de los… …   Wikipedia Español

  • Literatura del Romanticismo en Francia — Ingres La apoteosis de Homero (Museo del Louvre). El Romanticismo es una corriente artística de Europa occidental que inició a lo largo del siglo XVIII en Gran Bretaña (Outre Manche) y en Alemania (Outre Rhin), extendiéndose …   Wikipedia Español

  • Música medieval — Este artículo o sección necesita referencias que aparezcan en una publicación acreditada, como revistas especializadas, monografías, prensa diaria o páginas de Internet fidedignas. Puedes añadirlas así o avisar a …   Wikipedia Español

  • Música en la Edad Media — Saltar a navegación, búsqueda La música medieval está formada por dos periodos principales: el Románico y el Gótico. Esta época se extiende desde el siglo V hasta el siglo XV. Dentro de la música medieval se pueden distinguir diferentes fenómenos …   Wikipedia Español

Compartir el artículo y extractos

Link directo
Do a right-click on the link above
and select “Copy Link”