{"id":5228,"date":"2025-12-18T12:24:49","date_gmt":"2025-12-18T11:24:49","guid":{"rendered":"https:\/\/sutilweb.eu\/?page_id=5228"},"modified":"2025-12-18T12:24:49","modified_gmt":"2025-12-18T11:24:49","slug":"26-traits-en-php","status":"publish","type":"page","link":"https:\/\/sutilweb.eu\/index.php\/lenguajes\/php\/php-practico\/26-traits-en-php\/","title":{"rendered":"26. Traits en PHP"},"content":{"rendered":"\n<p>En cap\u00edtulo pasados habl\u00e1bamos sobre la&nbsp;<strong>herencia<\/strong>, la cual consiste en que nosotros podemos definir una clase padre, la cual tiene cierta cantidad de propiedades y m\u00e9todos, y posteriormente definir otras clases, las cuales extend\u00edan de la clase padre, heredando tanto sus propiedades como sus m\u00e9todos.<\/p>\n\n\n\n<p>En PHP la herencia es simple, lo que significa que una clase s\u00f3lo puede heredar de una y s\u00f3lo una clase padre. Existen otros lenguajes orientados a objetos, como son C++, que permiten que una clase hija herede de varias clases padre, pero no es el caso de PHP.&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Simular herencia m\u00faltiple<\/h2>\n\n\n\n<p>Para simular la herencia m\u00faltiple, en PHP podemos hacer uso de los traits.<\/p>\n\n\n\n<p><strong>Ejm<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>  &lt;?php\n\n  class Persona {\n    public function setNombre($nombre){\n      $this->nombre = $nombre;\n    }\n\n    public function getNombre(){\n      return ucwords($this->nombre);\n    }\n  }\n\n  trait Latinoamericano {\n    public function saludoLatinoamericano(){\n      echo \"Este es un saludo latinoamericano\"\n    }\n  }\n\n  trait Europeo {\n    public function saludoEuropeo(){\n      echo \"Este es un saludo europeo\";\n    }\n  }\n\n  class Peruano extends Persona {\n    use Lainoamericano;\n    \/\/ Con esto conseguimos que herede tanto de la clase Persona como de la clase Latinoamericano\n  }\n\n\n  class Aleman extends Persona {\n    use Europeo;\n    \/\/ Con esto conseguimos que herede tanto de la clase Persona como de la clase Europeo\n  }\n\n  $peruano = new Peruano;\n  $peruano->saludoLatinoamericano();<\/code><\/pre>\n\n\n\n<p>Una de las principales diferencias entre una <strong>clase<\/strong> y un <strong>trait<\/strong> es que los traits no se pueden instanciar. Los traits s\u00f3lo se van a utilizar para poder extender las propiedades y m\u00e9todos de una determinada clase.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Presencia<\/h2>\n\n\n\n<p>Cuando implementamos un trait, \u00e9ste sobreescribe cualquier m\u00e9todo de la clase padre que lleve el mismo nombre.<\/p>\n\n\n\n<p><strong>Ejm<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>  &lt;?php\n\n  class Persona {\n    public $nombre;\n\n    public function saludo(){\n      echo \"Hola\";\n    }\n\n    public function setNombre($nombre){\n      $this->nombre = $nombre;\n    }\n\n    public function getNombre(){\n      return ucwords($this->nombre);\n    }\n  }\n\n  trait Latinoamericano {\n    public function saludo(){\n      echo \"Hola Mundo\";\n    }\n  }\n\n  class Peruano extends Persona {\n    use Lainoamericano;\n    \/\/ Con esto conseguimos que herede tanto de la clase Persona como de la clase Latinoamericano\n  }\n\n  $peruano = new Peruano;\n  $peruano->saludo();<\/code><\/pre>\n\n\n\n<p>Igualmente, si existe el mismo m\u00e9todo en la clase hija que hereda tanto de la clase padre como del trait, ese ser\u00e1 el m\u00e9todo que se ejecutar\u00e1 si instanciamos sobre la clase hija, es decir, el m\u00e9todo de la clase hija sobreescribir\u00e1 el de la clase padre y el del trait, al igual que el m\u00e9todo del trait ha sobreescrito el de la clase padre.<\/p>\n\n\n\n<p><strong>Ejm<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>  &lt;?php\n\n  class Persona {\n    public $nombre;\n\n    public function saludo(){\n      echo \"Hola\";\n    }\n\n    public function setNombre($nombre){\n      $this->nombre = $nombre;\n    }\n\n    public function getNombre(){\n      return ucwords($this->nombre);\n    }\n  }\n\n  trait Latinoamericano {\n    public function saludo(){\n      echo \"Hola Mundo\";\n    }\n  }\n\n  class Peruano extends Persona {\n    use Lainoamericano;\n    \/\/ Con esto conseguimos que herede tanto de la clase Persona como de la clase Latinoamericano\n\n    public function saludo(){\n      echo \"Hola Mundo desde la clase peruano\";\n    }\n  }\n\n  $peruano = new Peruano;\n  $peruano->saludo();<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Uso de m\u00e1s de un trait<\/h2>\n\n\n\n<p>Para ello utilizamos la sintaxis del ejm.<\/p>\n\n\n\n<p><strong>Ejm<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>  &lt;?php\n\n  class Persona {\n    public $nombre;\n\n    public function saludo(){\n      echo \"Hola\";\n    }\n\n    public function setNombre($nombre){\n      $this->nombre = $nombre;\n    }\n\n    public function getNombre(){\n      return ucwords($this->nombre);\n    }\n  }\n\n  trait hola {\n    public function decirHola(){\n      echo \"Hola\";\n    }\n  }\n\n  trait mundo {\n    public function decirMundo(){\n      echo \"mundo\";\n    }\n  }\n\n\n  class Peruano extends Persona {\n    use hola, mundo;\n    \/\/ Con esto conseguimos que herede tanto de la clase Persona como de las traits hola y mundo\n\n    public function saludo(){\n      echo \"Hola Mundo desde la clase peruano\";\n    }\n  }\n\n  $peruano = new Peruano;\n  $peruano->decirHola();\n  $peruano->decirMundo();  \/\/ Imprimir\u00e1 hola mundo<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Uso de&nbsp;mismos m\u00e9todos en los traits<\/h2>\n\n\n\n<p>Si tenemos dos traits que utilizan un m\u00e9todo con el mismo nombre, dichos m\u00e9todos entrar\u00e1n en conflicto, para ello podemos utilizar la sintaxis del siguiente ejm para elegir uno de los m\u00e9todos.<\/p>\n\n\n\n<p><strong>Ejm<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>  &lt;?php\n\n  class Persona {\n    public $nombre;\n\n    public function saludo(){\n      echo \"Hola\";\n    }\n\n    public function setNombre($nombre){\n      $this->nombre = $nombre;\n    }\n\n    public function getNombre(){\n      return ucwords($this->nombre);\n    }\n  }\n\n  trait A {\n    public function saludo(){\n      echo \"Hola mundo desde el trait A\";\n    }\n  }\n\n  trait B {\n    public function saludo(){\n      echo \"Hola mundo desde el trait B\";\n  }\n\n\n class Peruano extends Persona {\n    use A, B {\n      \/\/ Queremos utilizar el m\u00e9todo saludo del trait A  y no del trait B\n      A::saludo insteadOf B;\n    }\n    \/\/ Con esto conseguimos que herede tanto de la clase Persona como de las traits hola y mundo\n\n    public function saludo(){\n      echo \"Hola Mundo desde la clase peruano\";\n    }\n  }\n\n  $peruano = new Peruano;\n  $peruano->decirHola();\n  $peruano->decirMundo();  \/\/ Imprimir\u00e1 hola mundo<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">M\u00e9todos protegidos en traits<\/h2>\n\n\n\n<p>Si queremos que un m\u00e9todo protegido en un trait se transforme en p\u00fablico podemos&nbsp;utilizar la sintaxis del siguiente ejm.<\/p>\n\n\n\n<p><strong>Ejm<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>  &lt;?php\n\n  class Persona {\n    public $nombre;\n\n    public function saludo(){\n      echo \"Hola\";\n    }\n\n    public function setNombre($nombre){\n      $this->nombre = $nombre;\n    }\n\n    public function getNombre(){\n      return ucwords($this->nombre);\n    }\n  }\n\n  trait A {\n    protected function saludo(){\n      echo \"Hola mundo desde el trait A\";\n    }\n  }\n\n  class Peruano extends Persona {\n    use A { saludo as public; }\n  }\n\n  $peruano = new Peruano;\n  $peruano->saludo();<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Uso de traits compuestos de otros traits<\/h2>\n\n\n\n<p>Podemos usar traits compuestos de otros traits mediante la siguiente sintaxis.<\/p>\n\n\n\n<p><strong>Ejm<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>  &lt;?php\n\n  class Persona {\n    public $nombre;\n\n    public function saludo(){\n      echo \"Hola\";\n    }\n\n    public function setNombre($nombre){\n      $this->nombre = $nombre;\n    }\n\n    public function getNombre(){\n      return ucwords($this->nombre);\n    }\n  }\n\n  trait A {\n    public function decirHola(){\n      echo \"Hola\";\n    }\n  }\n\n  trait B {\n    public function decirMundo(){\n      echo \"Mundo\";\n    }\n  }\n\n  trait C {\n    use A, B;\n  }\n\n  class Peruano extends Persona {\n    use C;\n  }\n\n  $peruano = new Peruano;\n  $peruano->decirHola();\n  $peruano->decirMundo();<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">M\u00e9todos abstractos<\/h2>\n\n\n\n<p>En los traits tambi\u00e9n podemos definir m\u00e9todos abstractos.<\/p>\n\n\n\n<p><strong>Ejm<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>  &lt;?php\n\n  class Persona {\n    public $nombre;\n\n    public function saludo(){\n      echo \"Hola\";\n    }\n\n    public function setNombre($nombre){\n      $this->nombre = $nombre;\n    }\n\n    public function getNombre(){\n      return ucwords($this->nombre);\n    }\n  }\n\n  trait A {\n    public function decirHola(){\n      echo \"Hola\";\n    }\n  }\n\n  trait B {\n    public function decirMundo(){\n      echo \"Mundo\";\n    }\n\n    abstract public function saludar();\n  }\n\n  trait C {\n    use A, B;\n\n    public function saludar(){\n      $this->decirHola();\n      $this->decirMundo();\n    }\n  }\n\n  class Peruano extends Persona {\n    use C;\n  }\n\n  $peruano = new Peruano;\n  $peruano->saludar();<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>En cap\u00edtulo pasados habl\u00e1bamos sobre la&nbsp;herencia, la cual consiste en que nosotros podemos definir una clase padre, la cual tiene [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":4518,"menu_order":25,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_uag_custom_page_level_css":"","site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"class_list":["post-5228","page","type-page","status-publish","hentry"],"uagb_featured_image_src":{"full":false,"thumbnail":false,"medium":false,"medium_large":false,"large":false,"1536x1536":false,"2048x2048":false},"uagb_author_info":{"display_name":"Sutil Web","author_link":"https:\/\/sutilweb.eu\/index.php\/author\/sutilweb\/"},"uagb_comment_info":0,"uagb_excerpt":"En cap\u00edtulo pasados habl\u00e1bamos sobre la&nbsp;herencia, la cual consiste en que nosotros podemos definir una clase padre, la cual tiene [&hellip;]","_links":{"self":[{"href":"https:\/\/sutilweb.eu\/index.php\/wp-json\/wp\/v2\/pages\/5228","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sutilweb.eu\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/sutilweb.eu\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/sutilweb.eu\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/sutilweb.eu\/index.php\/wp-json\/wp\/v2\/comments?post=5228"}],"version-history":[{"count":10,"href":"https:\/\/sutilweb.eu\/index.php\/wp-json\/wp\/v2\/pages\/5228\/revisions"}],"predecessor-version":[{"id":5238,"href":"https:\/\/sutilweb.eu\/index.php\/wp-json\/wp\/v2\/pages\/5228\/revisions\/5238"}],"up":[{"embeddable":true,"href":"https:\/\/sutilweb.eu\/index.php\/wp-json\/wp\/v2\/pages\/4518"}],"wp:attachment":[{"href":"https:\/\/sutilweb.eu\/index.php\/wp-json\/wp\/v2\/media?parent=5228"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}