stringtranslate.com

es-un

En la representación del conocimiento y los componentes de ontología , incluso para la programación y el diseño orientados a objetos , is-a (también escrito como is_a o is a ) es una relación subsuntiva [a] entre abstracciones (por ejemplo, tipos , clases ), en donde una clase A es una subclase de otra clase B (y por lo tanto B es una superclase de A ). En otras palabras, el tipo A es un subtipo del tipo B cuando la especificación de A implica la especificación de B. Es decir, cualquier objeto (o clase) que satisface la especificación de A también satisface la especificación de B, porque la especificación de B es más débil. [1]

Por ejemplo, un gato "es" un animal, pero no al revés. Todos los gatos son animales, pero no todos los animales son gatos. El comportamiento que es relevante para todos los animales se define en una clase animal, mientras que el comportamiento que es relevante solo para los gatos se define en una clase gato. Al definir la clase gato como "extensión" de la clase animal, todos los gatos "heredan" el comportamiento definido para los animales, sin la necesidad de codificar explícitamente ese comportamiento para los gatos.

Conceptos relacionados

La relación es-un debe contrastarse con la relación tiene-un ( has_a o has a ) entre tipos (clases); confundir las relaciones tiene-un e es-un es un error común al diseñar un modelo (por ejemplo, un programa de computadora ) de la relación del mundo real entre un objeto y su subordinado. La relación es-un también puede contrastarse con la relación instancia-de entre objetos (instancias) y tipos (clases): vea Distinción entre tipo y token .

Para resumir las relaciones existen:

Ejemplos de subtipificación

La subtipificación permite sustituir un tipo determinado por otro tipo o abstracción. Se dice que la subtipificación establece una relación de tipo "es-un" entre el subtipo y alguna abstracción existente, ya sea de forma implícita o explícita, según el soporte del lenguaje. La relación se puede expresar explícitamente a través de la herencia en lenguajes que admiten la herencia como mecanismo de subtipificación.

C++

El siguiente código C++ establece una relación de herencia explícita entre las clases B y A , donde B es a la vez una subclase y un subtipo de A , y puede usarse como una A dondequiera que se especifique una B (a través de una referencia, un puntero o el objeto mismo).

clase A { público : void DoSomethingALike () const {} };      clase B : público A { público : void DoSomethingBlike () const {} };         void UseAnA ( A const & some_A ) { some_A.DoSomethingALike ( ) ; }    void SomeFunc () { B b ; UseAnA ( b ); // b se puede sustituir por una A. }     

[3]

Pitón

El siguiente código de Python establece una relación de herencia explícita entre las clases B y A , donde B es a la vez una subclase y un subtipo de A , y puede usarse como una A dondequiera que se requiera una B.

clase  A :  def  hacer_algo_similar ( self ):  pasarclase  B ( A ):  def  hacer_algo_b_como ( self ):  pasardef  use_an_a ( some_a ) :  some_a.do_algo_similar ( )def  some_func ():  b  =  B ()  use_an_a ( b )  # b puede sustituirse por una A.

En el siguiente ejemplo, type(a) es un tipo "regular" y type(type(a)) es un metatipo. Si bien todos los tipos distribuidos tienen el mismo metatipo ( PyType_Type , que también es su propio metatipo), esto no es un requisito. El tipo de clases clásicas, conocido como types.ClassType , también puede considerarse un metatipo distinto. [4]

>>> a  =  0 >>> tipo ( a ) <tipo 'int'> >>> tipo ( tipo ( a )) <tipo 'tipo'> >>> tipo ( tipo ( tipo ( a ))) <tipo 'tipo'> >>> tipo ( tipo ( tipo ( tipo ( a )))) <tipo 'tipo'>

Java

En Java, la relación entre los parámetros de tipo de una clase o interfaz y los parámetros de tipo de otra está determinada por las cláusulas extends e implements .

Usando las Collectionsclases, ArrayList<E>implementa List<E>y List<E>extiende Collection<E>. Por lo tanto , ArrayList<String>es un subtipo de List<String>, que es un subtipo de Collection<String>. La relación de subtipo se conserva automáticamente entre los tipos. Al definir una interfaz, PayloadList, que asocia un valor opcional de tipo genérico P con cada elemento, su declaración podría verse así:

interfaz  PayloadList < E , P > extiende List < E > { void setPayload ( int index , P val ); ... }          

Las siguientes parametrizaciones de PayloadList son subtipos de List<String>:

PayloadList < Cadena , Cadena > PayloadList < Cadena , Entero > PayloadList < Cadena , Excepción >   

Principio de sustitución de Liskov

El principio de sustitución de Liskov explica una propiedad: "Si para cada objeto o1 de tipo S hay un objeto o2 de tipo T tal que para todos los programas P definidos en términos de T, el comportamiento de P no cambia cuando o1 se sustituye por o2, entonces S es un subtipo de T" . [5] El siguiente ejemplo muestra una violación de LSP.

He aquí quizás un ejemplo de violación de la LSP:

clase Rectángulo { público : void SetWidth ( double w ) { suAncho = w ; } void SetHeight ( double h ) { suAltura = h ; } doble ObtenerAltura () const { devuelve suAltura ; } doble ObtenerAncho () const { devuelve suAncho ; } doble ObtenerArea () const { devuelve ObtenerAltura () * ObtenerAncho (); } privado : doble suAncho ; doble suAltura ; };                                              

Desde un punto de vista de programación, la clase Cuadrado puede implementarse heredando de la clase Rectángulo.

clase pública Cuadrado : Rectángulo { público : virtual void EstablecerAncho ( double w ); virtual void EstablecerAltura ( double h ); }; void Cuadrado::EstablecerAncho ( double w ) { Rectángulo :: EstablecerAncho ( w ); Rectángulo :: EstablecerAltura ( w ); } void Cuadrado::EstablecerAltura ( double h ) { Rectángulo :: EstablecerAltura ( h ); Rectángulo :: EstablecerAncho ( h ); }                     

Sin embargo, esto viola LSP aunque la relación es-un se mantiene entre Rectángulo y Cuadrado.

Consideremos el siguiente ejemplo, donde la función g no funciona si se pasa un cuadrado, por lo que se podría considerar que se ha violado el principio de apertura-cerrado.

void g ( Rectangle & r ) { r . SetWidth ( 5 ); r . SetHeight ( 4 ); assert ( r . GetArea ()) == 20 ); // la afirmación fallará }        

Por el contrario, si uno considera que el tipo de una forma solo debe ser una restricción en la relación de sus dimensiones, entonces la suposición en g() de que SetHeight cambiará la altura y el área, pero no el ancho, es inválida, no solo para cuadrados verdaderos, sino incluso potencialmente para otros rectángulos que podrían estar codificados para preservar el área o la relación de aspecto cuando cambia la altura.

[6]

Véase también

Notas

  1. ^ "Subtipos y subclases" (PDF) . MIT OCW . Consultado el 2 de octubre de 2012 .
  2. ^ Véase también Contención (programación informática) .
  3. ^ Mitchell, John (2002). "10 "Conceptos en lenguajes orientados a objetos"". Conceptos en lenguaje de programación . Cambridge, Reino Unido: Cambridge University Press. p. 287. ISBN 0-521-78098-5.
  4. ^ Guido van Rossum. "Subtipificación de tipos integrados" . Consultado el 2 de octubre de 2012 .
  5. ^ Liskov, Barbara (mayo de 1988). Abstracción y jerarquía de datos (PDF) . Avisos SIGPLAN. Archivado desde el original el 21 de junio de 2020.{{cite book}}: CS1 maint: unfit URL (link)
  6. ^ "El principio de sustitución de Liskov" (PDF) . Robert C. Martin, 1996. Archivado desde el original (PDF) el 5 de septiembre de 2015 . Consultado el 2 de octubre de 2012 .

Referencias