{"id":334,"date":"2023-06-26T08:10:00","date_gmt":"2023-06-26T08:10:00","guid":{"rendered":"https:\/\/jorgeturiel.es\/?p=334"},"modified":"2023-08-11T21:15:03","modified_gmt":"2023-08-11T20:15:03","slug":"introduccion-al-lenguaje-pascal-moderno-para-programadores-parte-8","status":"publish","type":"post","link":"https:\/\/jorgeturiel.es\/?p=334","title":{"rendered":"Introducci\u00f3n al lenguaje Pascal moderno para programadores (Parte 8)"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Caracter\u00edsticas de las clases avanzadas<\/h2>\n\n\n\n<p id=\"block-5521090e-ab25-4c7d-8ff9-7b06a21f4a1b\">Continuamos con la introducci\u00f3n al lenguaje Pascal Moderno.<\/p>\n\n\n\n<p id=\"block-404f08e6-e309-4eb0-84cf-cdf990136039\">Esta entrada es una traducci\u00f3n al espa\u00f1ol, del texto <a rel=\"noreferrer noopener\" href=\"https:\/\/castle-engine.io\/modern_pascal\" target=\"_blank\">original<\/a> escrito por Michalis Kamburelis.<\/p>\n\n\n\n<!--more-->\n\n\n\n<h2 class=\"wp-block-heading\">Privado y estrictamente privado<\/h2>\n\n\n\n<p> <p>El especificador de visibilidad privada significa que el campo (o m\u00e9todo) no es accesible fuera de esta clase. Pero permite una excepci\u00f3n: todo el c\u00f3digo definido en la misma unidad puede romper esto y acceder a campos y m\u00e9todos privados. Un programador de C++ dir\u00eda que en Pascal todas las clases dentro de una sola unidad son amigas. Esto suele ser \u00fatil y no rompe la encapsulaci\u00f3n, ya que est\u00e1 limitado a una unidad.   Sin embargo, si crea unidades m\u00e1s grandes, con muchas clases (que no est\u00e1n estrechamente integradas entre s\u00ed), es m\u00e1s seguro usar la privacidad estricta. Significa que el campo (o m\u00e9todo) no es accesible fuera de este per\u00edodo de clase. Sin excepciones.   De manera similar, hay visibilidad protegida (visible para los descendientes o amigos en la misma unidad) y protecci\u00f3n estricta (visible para los descendientes, punto).<\/p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">M\u00e1s cosas dentro de clases y clases anidadas <\/h2>\n\n\n\n<p>Puede abrir una secci\u00f3n de constantes (const) o tipos (tipo) dentro de una clase. De esta manera, incluso puede definir una clase dentro de una clase. Los especificadores de visibilidad funcionan como siempre, en particular, la clase anidada puede ser privada (no visible para el mundo exterior), lo que suele ser \u00fatil.<\/p>\n\n\n\n<p>Tenga en cuenta que para declarar un campo despu\u00e9s de una constante o tipo, deber\u00e1 abrir un bloque var.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \">type\n  TMyClass = class\n  private\n    type\n      TInternalClass = class\n        Velocity: Single;\n        procedure DoSomething;\n      end;\n    var\n      FInternalClass: TInternalClass;\n  public\n    const\n      DefaultVelocity = 100.0;\n    constructor Create;\n    destructor Destroy; override;\n  end;\n\nconstructor TMyClass.Create;\nbegin\n  inherited;\n  FInternalClass := TInternalClass.Create;\n  FInternalClass.Velocity := DefaultVelocity;\n  FInternalClass.DoSomething;\nend;\n\ndestructor TMyClass.Destroy;\nbegin\n  FreeAndNil(FInternalClass);\n  inherited;\nend;\n\n{ note that method definition is prefixed with\n  \"TMyClass.TInternalClass\" below. }\nprocedure TMyClass.TInternalClass.DoSomething;\nbegin\nend;<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">M\u00e9todos de clase<\/h2>\n\n\n\n<p>Estos son m\u00e9todos a los que puede llamar con una referencia de clase (TMyClass), no necesariamente una instancia de clase.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \">type\n  TEnemy = class\n    procedure Kill;\n    class procedure KillAll;\n  end;\n\nvar\n  E: TEnemy;\nbegin\n  E := TEnemy.Create;\n  try\n    E.Kill;\n  finally FreeAndNil(E) end;\n  TEnemy.KillAll;\nend;<\/pre><\/div>\n\n\n\n<p>Tenga en cuenta que pueden ser virtuales\u2009\u2014\u2009tiene sentido, y a veces es muy \u00fatil, cuando se combinan con referencias de clase.<\/p>\n\n\n\n<p>Los m\u00e9todos de clase tambi\u00e9n pueden estar limitados por los especificadores de visibilidad, como privado o protegido. Al igual que los m\u00e9todos regulares.<\/p>\n\n\n\n<p>Tenga en cuenta que un constructor siempre act\u00faa como un m\u00e9todo de clase cuando se llama de forma normal (MyInstance := TMyClass.Create(\u2026\u200b);). Aunque tambi\u00e9n es posible llamar a un constructor desde dentro de la propia clase, como un m\u00e9todo normal, y luego act\u00faa como un m\u00e9todo normal. Esta es una caracter\u00edstica \u00fatil para \u00abencadenar\u00bb constructores, cuando un constructor (por ejemplo, sobrecargado para tomar un par\u00e1metro entero) hace alg\u00fan trabajo y luego llama a otro constructor (por ejemplo, sin par\u00e1metros).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Referencias de clase<\/h2>\n\n\n\n<p>La referencia de clase le permite elegir la clase en tiempo de ejecuci\u00f3n, por ejemplo, para llamar a un m\u00e9todo de clase o constructor sin conocer la clase exacta en tiempo de compilaci\u00f3n. Es un tipo declarado como clase de TMyClass.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \">type\n  TMyClass = class(TComponent)\n  end;\n\n  TMyClass1 = class(TMyClass)\n  end;\n\n  TMyClass2 = class(TMyClass)\n  end;\n\n  TMyClassRef = class of TMyClass;\n\nvar\n  C: TMyClass;\n  ClassRef: TMyClassRef;\nbegin\n  \/\/ Obviously you can do this:\n\n  C := TMyClass.Create(nil); FreeAndNil(C);\n  C := TMyClass1.Create(nil); FreeAndNil(C);\n  C := TMyClass2.Create(nil); FreeAndNil(C);\n\n  \/\/ In addition, using class references, you can also do this:\n\n  ClassRef := TMyClass;\n  C := ClassRef.Create(nil); FreeAndNil(C);\n\n  ClassRef := TMyClass1;\n  C := ClassRef.Create(nil); FreeAndNil(C);\n\n  ClassRef := TMyClass2;\n  C := ClassRef.Create(nil); FreeAndNil(C);\nend;<\/pre><\/div>\n\n\n\n<p>Las referencias de clase se pueden combinar con m\u00e9todos de clase virtual. Esto da un efecto similar al uso de clases con m\u00e9todos virtuales\u2009\u2014\u2009el m\u00e9todo real que se ejecutar\u00e1 se determina en tiempo de ejecuci\u00f3n.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \">type\n  TMyClass = class(TComponent)\n    class procedure DoSomething; virtual; abstract;\n  end;\n\n  TMyClass1 = class(TMyClass)\n    class procedure DoSomething; override;\n  end;\n\n  TMyClass2 = class(TMyClass)\n    class procedure DoSomething; override;\n  end;\n\n  TMyClassRef = class of TMyClass;\n\nvar\n  C: TMyClass;\n  ClassRef: TMyClassRef;\nbegin\n  ClassRef := TMyClass1;\n  ClassRef.DoSomething;\n\n  ClassRef := TMyClass2;\n  ClassRef.DoSomething;\n\n  { And this will cause an exception at runtime,\n    since DoSomething is abstract in TMyClass. }\n  ClassRef := TMyClass;\n  ClassRef.DoSomething;\nend;<\/pre><\/div>\n\n\n\n<p>Si tiene una instancia y desea obtener una referencia a su clase (no la clase declarada, sino la clase descendiente final utilizada en su construcci\u00f3n), puede usar la propiedad ClassType. El tipo declarado de ClassType es TClass, que significa clase de TObject. A menudo, puede encasillarlo de manera segura en algo m\u00e1s espec\u00edfico, cuando sabe que la instancia es algo m\u00e1s espec\u00edfico que TObject.<\/p>\n\n\n\n<p>En particular, puede usar la referencia ClassType para llamar a m\u00e9todos virtuales, incluidos los constructores virtuales. Esto le permite crear un m\u00e9todo como Clone que construye una instancia de la clase de tiempo de ejecuci\u00f3n exacta del objeto actual. Puede combinarlo con Cloning: TPersistent.Assign para tener un m\u00e9todo que devuelva un clon reci\u00e9n construido de la instancia actual.<\/p>\n\n\n\n<p>Recuerda que solo funciona cuando el constructor de tu clase es virtual. Por ejemplo, se puede usar con los descendientes est\u00e1ndar de TComponent, ya que todos deben anular el constructor virtual TComponent.Create(AOwner: TComponent).<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \">type\n  TMyClass = class(TComponent)\n    procedure Assign(Source: TPersistent); override;\n    function Clone(AOwner: TComponent): TMyClass;\n  end;\n\n  TMyClassRef = class of TMyClass;\n\nfunction TMyClass.Clone(AOwner: TComponent): TMyClass;\nbegin\n  \/\/ This would always create an instance of exactly TMyClass:\n  \/\/Result := TMyClass.Create(AOwner);\n  \/\/ This can potentially create an instance of TMyClass descendant:\n  Result := TMyClassRef(ClassType).Create(AOwner);\n  Result.Assign(Self);\nend;<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">M\u00e9todos de clase est\u00e1tica<\/h2>\n\n\n\n<p>Para comprender los m\u00e9todos de clase est\u00e1ticos, debe comprender c\u00f3mo funcionan los m\u00e9todos de clase normales (descritos en las secciones anteriores). Internamente, los m\u00e9todos de clase normales reciben una referencia de clase de su clase (se pasa a trav\u00e9s de un primer par\u00e1metro del m\u00e9todo oculto e impl\u00edcitamente agregado). Incluso se puede acceder a esta referencia de clase expl\u00edcitamente usando la palabra clave Self dentro del m\u00e9todo de clase. Por lo general, es algo bueno: esta referencia de clase le permite llamar a m\u00e9todos de clases virtuales (a trav\u00e9s de la tabla de m\u00e9todos virtuales de la clase).<\/p>\n\n\n\n<p>Si bien esto es bueno, hace que los m\u00e9todos de clase normales sean incompatibles cuando se asignan a un puntero de procedimiento global. Es decir, esto no compilar\u00e1:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \">{$mode objfpc}{$H+}{$J-}\ntype\n  TMyCallback = procedure (A: Integer);\n\n  TMyClass = class\n    class procedure Foo(A: Integer);\n  end;\n\nclass procedure TMyClass.Foo(A: Integer);\nbegin\nend;\n\nvar\n  Callback: TMyCallback;\nbegin\n  \/\/ Error: TMyClass.Foo not compatible with TMyCallback\n  Callback := @TMyClass(nil).Foo;\nend.<\/pre><\/div>\n\n\n\n<p>Nota: En el modo Delphi, podr\u00eda escribir TMyClass.Foo en lugar de un feo TMyClass(nil).Foo en el ejemplo anterior. Es cierto que TMyClass.Foo se ve mucho m\u00e1s elegante y el compilador tambi\u00e9n lo verifica mejor. Usar TMyClass(nil).Foo es un truco\u2026 desafortunadamente, necesario (por ahora) en el modo ObjFpc que se presenta a lo largo de este libro.<\/p>\n\n\n\n<p>En cualquier caso, la asignaci\u00f3n de TMyClass.Foo a la devoluci\u00f3n de llamada anterior a\u00fan fallar\u00eda en el modo Delphi, exactamente por las mismas razones.<\/p>\n\n\n\n<p>El ejemplo anterior no se compila porque Callback es incompatible con el m\u00e9todo de clase Foo. Y es incompatible porque internamente el m\u00e9todo de clase tiene ese par\u00e1metro impl\u00edcito oculto especial para pasar una referencia de clase.<\/p>\n\n\n\n<p>Una forma de corregir el ejemplo anterior es cambiar la definici\u00f3n de TMyCallback. Funcionar\u00e1 si se trata de una devoluci\u00f3n de llamada de m\u00e9todo, declarada como TMyCallback = procedimiento (A: Integer) of object;. Pero a veces, no es deseable.<\/p>\n\n\n\n<p>Aqu\u00ed viene el m\u00e9todo de clase est\u00e1tica. Es, en esencia, solo un procedimiento\/funci\u00f3n global, pero su espacio de nombres est\u00e1 limitado dentro de la clase. No tiene ninguna referencia de clase impl\u00edcita (y por lo tanto, no puede ser virtual y no puede llamar a m\u00e9todos de clase virtual). Por el lado positivo, es compatible con las devoluciones de llamadas normales (sin objetos). As\u00ed que esto funcionar\u00e1:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \">{$mode objfpc}{$H+}{$J-}\ntype\n  TMyCallback = procedure (A: Integer);\n\n  TMyClass = class\n    class procedure Foo(A: Integer); static;\n  end;\n\nclass procedure TMyClass.Foo(A: Integer);\nbegin\nend;\n\nvar\n  Callback: TMyCallback;\nbegin\n  Callback := @TMyClass.Foo;\nend.<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Propiedades de clase y variables<\/h2>\n\n\n\n<p>Una propiedad de clase es una propiedad a la que se puede acceder a trav\u00e9s de una referencia de clase (no necesita una instancia de clase).<\/p>\n\n\n\n<p>Es una analog\u00eda bastante directa de una propiedad regular (ver Propiedades). Para una propiedad de clase, define un getter y\/o un setter. Pueden hacer referencia a una variable de clase o a un m\u00e9todo de clase est\u00e1tico.<\/p>\n\n\n\n<p>Una variable de clase es, lo adivin\u00f3, como un campo normal, pero no necesita una instancia de clase para acceder a ella. En efecto, es como una variable global, pero con el espacio de nombres limitado a la clase contenedora. Se puede declarar dentro de la secci\u00f3n class var de la clase. Alternativamente, se puede declarar siguiendo la definici\u00f3n de campo normal con la palabra clave static.<\/p>\n\n\n\n<p>Y un m\u00e9todo de clase est\u00e1tica es como un procedimiento\/funci\u00f3n global, pero con el espacio de nombres limitado a la clase contenedora. Para obtener m\u00e1s informaci\u00f3n sobre los m\u00e9todos de clase est\u00e1ticos en la secci\u00f3n anterior, consulte M\u00e9todos de clase est\u00e1ticos.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \">{$mode objfpc}{$H+}{$J-}\ntype\n  TMyClass = class\n  strict private\n    \/\/ Alternative:\n    \/\/ FMyProperty: Integer; static;\n    class var\n      FMyProperty: Integer;\n    class procedure SetMyProperty(const Value: Integer); static;\n  public\n    class property MyProperty: Integer\n      read FMyProperty write SetMyProperty;\n  end;\n\nclass procedure TMyClass.SetMyProperty(const Value: Integer);\nbegin\n  Writeln('MyProperty changes!');\n  FMyProperty := Value;\nend;\n\nbegin\n  TMyClass.MyProperty := 123;\n  Writeln('TMyClass.MyProperty is now ', TMyClass.MyProperty);\nend.<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Ayudantes de clase (Helpers)<\/h2>\n\n\n\n<p>El m\u00e9todo es solo un procedimiento o funci\u00f3n dentro de una clase. Desde el exterior de la clase, la llama con una sintaxis especial MyInstance.MyMethod(\u2026\u200b). Despu\u00e9s de un tiempo te acostumbras a pensar que si quiero hacer una acci\u00f3n Acci\u00f3n en la instancia X, escribo <code>X.Action(\u2026\u200b)<\/code>.<\/p>\n\n\n\n<p>Pero a veces, necesita implementar algo que conceptualmente es una acci\u00f3n en la clase TMyClass sin modificar el c\u00f3digo fuente de TMyClass. A veces es porque no es su c\u00f3digo fuente y no quiere cambiarlo. A veces se debe a las dependencias\u2009\u2014\u2009agregar un m\u00e9todo como Render a una clase como TMy3DObject parece una idea sencilla, pero tal vez la implementaci\u00f3n base de la clase TMy3DObject deber\u00eda mantenerse independiente del c\u00f3digo de renderizado. Ser\u00eda mejor \u00abmejorar\u00bb una clase existente, agregarle funcionalidad sin cambiar su c\u00f3digo fuente.<\/p>\n\n\n\n<p>Una forma sencilla de hacerlo es crear un procedimiento global que tome una instancia de TMy3DObject como su primer par\u00e1metro.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \">type\n  TMy3DObjectHelper = class helper for TMy3DObject\n    procedure Render(const Color: TColor);\n  end;\n\nprocedure TMy3DObjectHelper.Render(const Color: TColor);\nvar\n  I: Integer;\nbegin\n  { note that we access ShapesCount, Shape without any qualifiers here }\n  for I := 0 to ShapesCount - 1 do\n    RenderMesh(Shape[I].Mesh, Color);\nend;<\/pre><\/div>\n\n\n\n<p>El concepto m\u00e1s general es \u00abtype helper\u00bb. Al usarlos, puede agregar m\u00e9todos incluso a tipos primitivos, como enteros o enumeraciones. Tambi\u00e9n puede agregar \u00abayudantes de registro\u00bb a (lo adivin\u00f3\u2026) registros. Consulte <a rel=\"noreferrer noopener\" href=\"http:\/\/lists.freepascal.org\/fpc-announce\/2013-February\/000587.html\" target=\"_blank\">http:\/\/lists.freepascal.org\/fpc-announce\/2013-February\/000587.html<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Constructores virtuales, destructores<\/h2>\n\n\n\n<p>El nombre del destructor siempre es Destroy, es virtual (ya que puede llamarlo sin conocer la clase exacta en tiempo de compilaci\u00f3n) y sin par\u00e1metros.<\/p>\n\n\n\n<p>El nombre del constructor es por convenci\u00f3n Create.<\/p>\n\n\n\n<p>Puede cambiar este nombre, aunque tenga cuidado con esto: si define CreateMy, siempre redefina tambi\u00e9n el nombre Create, de lo contrario, el usuario a\u00fan puede acceder al constructor Create del antepasado, sin pasar por su constructor CreateMy.<\/p>\n\n\n\n<p>En el TObject base no es virtual, y al crear descendientes eres libre de cambiar los par\u00e1metros. El nuevo constructor ocultar\u00e1 el constructor en el ancestro (nota: no ponga aqu\u00ed sobrecarga, a menos que quiera romperlo).<\/p>\n\n\n\n<p>En los descendientes de TComponent, debe anular su constructor Create (AOwner: TComponent);. Para la funcionalidad de transmisi\u00f3n, para crear una clase sin conocer su tipo en el momento de la compilaci\u00f3n, es muy \u00fatil tener constructores virtuales (consulte Referencias de clase m\u00e1s arriba).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Una excepci\u00f3n en el constructor.<\/h2>\n\n\n\n<p>\u00bfQu\u00e9 sucede si ocurre una excepci\u00f3n durante un constructor? La l\u00ednea:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \">X := TMyClass.Create;<\/pre><\/div>\n\n\n\n<p>no se ejecuta hasta el final en este caso, no se puede asignar X, entonces, \u00bfqui\u00e9n limpiar\u00e1 despu\u00e9s de una clase parcialmente construida?<\/p>\n\n\n\n<p>La soluci\u00f3n de Object Pascal es que, en caso de que ocurra una excepci\u00f3n dentro de un constructor, se llama al destructor. Esta es una raz\u00f3n por la que su destructor debe ser robusto, lo que significa que deber\u00eda funcionar en cualquier circunstancia, incluso en una instancia de clase creada a medias. Por lo general, esto es f\u00e1cil si libera todo de forma segura, como FreeAndNil.<\/p>\n\n\n\n<p>Tambi\u00e9n tenemos que depender en tales casos de que se garantice que la memoria de la clase se ponga a cero justo antes de que se ejecute el c\u00f3digo del constructor. Entonces sabemos que al principio, todas las referencias de clase son nulas, todos los n\u00fameros enteros son 0 y as\u00ed sucesivamente.<\/p>\n\n\n\n<p>Entonces, a continuaci\u00f3n, funciona sin fugas de memoria:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \">{$mode objfpc}{$H+}{$J-}\nuses\n  SysUtils;\n\ntype\n  TGun = class\n  end;\n\n  TPlayer = class\n    Gun1, Gun2: TGun;\n    constructor Create;\n    destructor Destroy; override;\n  end;\n\nconstructor TPlayer.Create;\nbegin\n  inherited;\n  Gun1 := TGun.Create;\n  raise Exception.Create('Raising an exception from constructor!');\n  Gun2 := TGun.Create;\nend;\n\ndestructor TPlayer.Destroy;\nbegin\n  { in case since the constructor crashed, we can\n    have Gun1 &lt;&gt; nil and Gun2 = nil now. Deal with it.\n    ...Actually, in this case, FreeAndNil deals with it without\n    any additional effort on our side, because FreeAndNil checks\n    whether the instance is nil before calling its destructor. }\n  FreeAndNil(Gun1);\n  FreeAndNil(Gun2);\n  inherited;\nend;\n\nbegin\n  try\n    TPlayer.Create;\n  except\n    on E: Exception do\n      WriteLn('Caught ' + E.ClassName + ': ' + E.Message);\n  end;\nend.<\/pre><\/div>\n\n\n\n<figure class=\"wp-block-embed is-type-wp-embed is-provider-trasteando-por-vicio wp-block-embed-trasteando-por-vicio\"><div class=\"wp-block-embed__wrapper\">\n<blockquote class=\"wp-embedded-content\" data-secret=\"pW1LM6TT2P\"><a href=\"https:\/\/jorgeturiel.es\/?p=338\">Introducci\u00f3n al lenguaje Pascal moderno para programadores (Parte 9)<\/a><\/blockquote><iframe loading=\"lazy\" class=\"wp-embedded-content\" sandbox=\"allow-scripts\" security=\"restricted\" style=\"position: absolute; clip: rect(1px, 1px, 1px, 1px);\" title=\"\u00abIntroducci\u00f3n al lenguaje Pascal moderno para programadores (Parte 9)\u00bb \u2014 Trasteando por vicio\" src=\"https:\/\/jorgeturiel.es\/?p=338&#038;embed=true#?secret=Dni5jhk1NZ#?secret=pW1LM6TT2P\" data-secret=\"pW1LM6TT2P\" width=\"600\" height=\"338\" frameborder=\"0\" marginwidth=\"0\" marginheight=\"0\" scrolling=\"no\"><\/iframe>\n<\/div><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>Caracter\u00edsticas de las clases avanzadas Continuamos con la introducci\u00f3n al lenguaje Pascal Moderno. Esta entrada es una traducci\u00f3n al espa\u00f1ol, del texto original escrito por Michalis Kamburelis.<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[27,25,26],"tags":[22,23,21,24],"class_list":["post-334","post","type-post","status-publish","format-standard","hentry","category-lazarus","category-pascal","category-programacion","tag-delphi","tag-lazarus","tag-pascal","tag-programacion"],"_links":{"self":[{"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=\/wp\/v2\/posts\/334","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=334"}],"version-history":[{"count":6,"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=\/wp\/v2\/posts\/334\/revisions"}],"predecessor-version":[{"id":549,"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=\/wp\/v2\/posts\/334\/revisions\/549"}],"wp:attachment":[{"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=334"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=334"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=334"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}