{"id":569,"date":"2013-06-12T10:43:20","date_gmt":"2013-06-12T08:43:20","guid":{"rendered":"http:\/\/www.lafabriquedecode.com\/blog\/?p=569"},"modified":"2013-06-12T10:43:20","modified_gmt":"2013-06-12T08:43:20","slug":"php-classes-abstraites-et-interfaces","status":"publish","type":"post","link":"http:\/\/www.lafabriquedecode.com\/blog\/2013\/06\/php-classes-abstraites-et-interfaces\/","title":{"rendered":"PHP : classes abstraites et interfaces"},"content":{"rendered":"<p>Les interfaces, comme les classes abstraites, sont des unit\u00e9s de code dont la raison d&rsquo;\u00eatre est de contraindre une classe \u00e0 impl\u00e9menter des m\u00e9thodes, c&rsquo;est \u00e0 dire \u00e0 les concr\u00e9tiser ! Nous allons voir en d\u00e9tail ces diff\u00e9rentes mani\u00e8res de contraindre les comportements de nos classes.<br \/>\n<a href=\"http:\/\/www.lafabriquedecode.com\/blog\/wp-content\/uploads\/2013\/06\/connect.png\"><img loading=\"lazy\" src=\"http:\/\/www.lafabriquedecode.com\/blog\/wp-content\/uploads\/2013\/06\/connect.png\" alt=\"connect\" width=\"250\" height=\"177\" class=\"alignnone size-full wp-image-616\" \/><\/a><\/p>\n<h1>La classe abstraite<\/h1>\n<p>Une classe abstraite est avant tout une classe. Rien ne l&rsquo;oblige \u00e0 poss\u00e9der des m\u00e9thodes abstraites ! Elle peut m\u00eame \u00eatre vide :<\/p>\n<pre class=\"brush: php; title: ; notranslate\" title=\"\">\r\nabstract class EtreVivant {\r\n}\r\n<\/pre>\n<p>Par contre, d\u00e8s lors que vous mettez une m\u00e9thode abstraite dans une classe, vous devez d\u00e9clarer votre classe comme \u00e9tant abstraite !<\/p>\n<pre class=\"brush: php; title: ; notranslate\" title=\"\">\r\nabstract class EtreVivant {\r\n    abstract public function respirer();\r\n}\r\n<\/pre>\n<p>Seules les fonctions membres de votre classe abstraite peuvent \u00eatre abstraites, jamais les propri\u00e9t\u00e9s ! Une classe abstraite ne s&rsquo;instancie pas ! Si d&rsquo;aventure vous tentez d&rsquo;instancier EtreVivant, voici ce qui va vous arriver :<\/p>\n<pre>PHP Fatal error:  Cannot instantiate abstract class EtreVivant<\/pre>\n<p>Si ma classe abstraite ne peut pas s&rsquo;instancier, c&rsquo;est donc que pour l&rsquo;utiliser il ne me reste plus qu&rsquo;une option : la d\u00e9river !<\/p>\n<pre class=\"brush: php; title: ; notranslate\" title=\"\">\r\nabstract class EtreVivant {\r\n    abstract public function respirer();\r\n}\r\n\r\nclass EtreHumain extends EtreVivant {\r\n}\r\n<\/pre>\n<p>En l&rsquo;\u00e9tat actuel de notre hi\u00e9rarchie d&rsquo;h\u00e9ritage, une erreur va se produire car EtreVivant nous <strong>impose<\/strong> d&rsquo;\u00e9crire respirer(), m\u00eame vide, ce que nous ne faisons pas !<\/p>\n<pre>PHP Fatal error:  Class EtreHumain contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (<strong>EtreVivant::respirer<\/strong>)\r\n<\/pre>\n<pre class=\"brush: php; title: ; notranslate\" title=\"\">\r\nabstract class EtreVivant {\r\n    abstract public function respirer();\r\n}\r\n\r\nclass EtreHumain extends EtreVivant {\r\n    public function respirer() {\r\n        \/\/TODO...\r\n    }\r\n}\r\n<\/pre>\n<p>Une classe abstraite peut forcer les classes qui la d\u00e9rivent \u00e0 impl\u00e9menter des fonctions aux modes d&rsquo;acc\u00e8s autre que public&#8230;prot\u00e9g\u00e9 par exemple :<\/p>\n<pre class=\"brush: php; title: ; notranslate\" title=\"\">\r\nabstract class EtreVivant {\r\n    abstract protected function _respirer();\r\n}\r\n\r\nclass EtreHumain extends EtreVivant {\r\n    protected function _respirer() {\r\n        \/\/TODO...\r\n    }\r\n}\r\n<\/pre>\n<p>Evidemment, aucun int\u00e9r\u00eat \u00e0 mettre une m\u00e9thode priv\u00e9e ET abstraite dans la classe abstraite&#8230;Une m\u00e9thode priv\u00e9e n&rsquo;est pas transmise dans les classes filles, elle ne peut \u00eatre appel\u00e9e que dans cette classe m\u00eame, ce serait un grave contre-sens ! Si vous tentiez de le faire, vous seriez bien d\u00e9\u00e7u(e)s :<\/p>\n<pre>PHP Fatal error:  Abstract function EtreVivant::_respirer() cannot be declared private<\/pre>\n<p>Nous avons dit pr\u00e9c\u00e9demment qu&rsquo;une classe abstraite ne pouvait pas \u00eatre instanci\u00e9e. Mais cependant, rien ne l&#8217;emp\u00eache d&rsquo;avoir un constructeur ! C&rsquo;est \u00e9videmment la classe concr\u00e8te qui la d\u00e9rive qui pourra l&rsquo;utiliser :<\/p>\n<pre class=\"brush: php; title: ; notranslate\" title=\"\">\r\nabstract class Maman {\r\n    public function __construct() {\r\n        echo &quot;Vous \u00eates chez Maman&quot;;\r\n    }\r\n}\r\n\r\nclass Fiston extends Maman {}\r\n$fiston = new Fiston;\r\n<\/pre>\n<h2>Quel int\u00e9r\u00eat ?<\/h2>\n<p>Vous utilisez des classes abstraites d\u00e8s lors qu&rsquo;un comportement est susceptible de varier selon la classe concr\u00e8te dans laquelle il se trouve&#8230;Regardez notre classe EtreVivant : elle est g\u00e9n\u00e9rique, c&rsquo;est ce que l&rsquo;on nomme un super-type ! Sa m\u00e9thode respirer() est elle aussi bien trop \u00ab\u00a0vague\u00a0\u00bb, les \u00eatres vivants respirent de bien des fa\u00e7ons diff\u00e9rentes ! Nous laissons donc le soin aux classes qui vont nous d\u00e9river de donner un corps \u00e0 cette m\u00e9thode, pire que \u00e7a, m\u00eame: nous l&rsquo;imposons !<\/p>\n<pre class=\"brush: php; title: ; notranslate\" title=\"\">\r\nabstract class EtreVivant {\r\n    abstract public function respirer();\r\n}\r\n\r\nclass EtreHumain extends EtreVivant {\r\n    public function respirer() {\r\n        echo 'Par le nez et\/ou la bouche';\r\n    }\r\n}\r\n\r\nclass Plante extends EtreVivant {\r\n    public function respirer() {\r\n        echo 'Par la photo-synth\u00e8se';\r\n    }\r\n}\r\n<\/pre>\n<p>Il existe bel et bien une notion de <strong>contrainte<\/strong> entre une classe abstraite contenant des m\u00e9thodes abstraites et sa descendance :<\/p>\n<blockquote><p>Si tu choisis d&rsquo;\u00eatre un EtreVivant, tu dois savoir respirer, peu m&rsquo;importe comment !<\/p><\/blockquote>\n<p>Une classe abstraite peut constituer un d\u00e9but d&rsquo;impl\u00e9mentation : elle poss\u00e8de des propri\u00e9t\u00e9s (un \u00e9tat) factorisables \u00e0 son niveau et des m\u00e9thodes (un comportement) qui amorcent une impl\u00e9mentation. Par exemple, nous avons rajout\u00e9 dans la classe abstraite une m\u00e9thode mourir qui fait appel \u00e0 une sous-m\u00e9thode _cesserFonctionsVitales qui sera impl\u00e9ment\u00e9e dans les classes d\u00e9riv\u00e9es :<\/p>\n<pre class=\"brush: php; title: ; notranslate\" title=\"\">\r\nabstract class EtreVivant {\r\n    protected $_age = 0;\r\n\tprotected $_poids = 0;\r\n\r\n\tpublic function mourir() {\r\n\t\t$this-&gt;_cesserFonctionsVitales();\r\n\t}\r\n\r\n    abstract public function respirer();\r\n    abstract protected function _cesserFonctionsVitales();\r\n}\r\n\r\nclass EtreHumain extends EtreVivant {\r\n    protected $_nationalite;\r\n\r\n    public function respirer() {\r\n        echo 'Par le nez et\/ou la bouche';\r\n    }\r\n\r\n    protected function _cesserFonctionsVitales() {\r\n        echo 'le coeur s\\'arr\u00eate de battre...AAAARGH';\r\n    }\r\n}\r\n\r\nclass HumainFrancais extends EtreHumain {\r\n    public function __construct() {\r\n        $this-&gt;_nationalite = 'fran\u00e7ais';\r\n    }\r\n}\r\n\r\n$francais = new HumainFrancais;\r\n$francais-&gt;mourir();\r\n<\/pre>\n<p>Une classe abstraite d\u00e9rivant une autre classe abstraite n&rsquo;est pas forc\u00e9e d&rsquo;impl\u00e9menter les m\u00e9thodes abstraites de sa m\u00e8re, vu qu&rsquo;elle est elle-m\u00eame abstraite&#8230;Par contre la premi\u00e8re classe concr\u00e8te rencontr\u00e9e dans l&rsquo;arbre d&rsquo;h\u00e9ritage en supportera les cons\u00e9quences ! Ceci va fonctionner car les deux classes sont abstraites (attention aux longues lign\u00e9es d&rsquo;h\u00e9ritage et aux trop nombreux niveaux d&rsquo;abstractions &#8211; \u00e0 partir de 3 &#8211; qui sont en g\u00e9n\u00e9ral le signe d&rsquo;une conception de pi\u00e8tre qualit\u00e9) :<\/p>\n<pre class=\"brush: php; title: ; notranslate\" title=\"\">\r\nabstract class EtreVivant {\r\n    protected $_age = 0;\r\n\tprotected $_poids = 0;\r\n\r\n\tpublic function mourir() {\r\n\t\t$this-&gt;_cesserFonctionsVitales();\r\n\t}\r\n\r\n    abstract public function respirer();\r\n    abstract protected function _cesserFonctionsVitales();\r\n}\r\n\r\nabstract class EtreHumain extends EtreVivant {\r\n}\r\n<\/pre>\n<p>si vous d\u00e9placez la responsabilit\u00e9 de l&rsquo;impl\u00e9mentation dans la premi\u00e8re classe rencontr\u00e9e dans l&rsquo;arbre d&rsquo;h\u00e9ritage, vous obtiendrez le code suivant :<\/p>\n<pre class=\"brush: php; title: ; notranslate\" title=\"\">\r\nabstract class EtreVivant {\r\n    protected $_age = 0;\r\n\tprotected $_poids = 0;\r\n\r\n\tpublic function mourir() {\r\n\t\t$this-&gt;_cesserFonctionsVitales();\r\n\t}\r\n\r\n    abstract public function respirer();\r\n    abstract protected function _cesserFonctionsVitales();\r\n}\r\n\r\nabstract class EtreHumain extends EtreVivant {\r\n    protected $_nationalite;\r\n\r\n}\r\n\r\nclass HumainFrancais extends EtreHumain {\r\n\r\n    public function respirer() {\r\n        echo 'Par le nez et\/ou la bouche';\r\n    }\r\n\r\n    protected function _cesserFonctionsVitales() {\r\n        echo 'le coeur s\\'arr\u00eate de battre...AAAARGH';\r\n    }\r\n\r\n    public function __construct() {\r\n        $this-&gt;_nationalite = 'fran\u00e7ais';\r\n    }\r\n}\r\n\r\n$francais = new HumainFrancais;\r\n$francais-&gt;mourir();\r\n<\/pre>\n<p>Mais quelle abomination serait un code pareil ! Tout est fourr\u00e9 \u00e0 grands coups de pied dans la classe concr\u00e8te HumainFrancais&#8230;Si demain nous devions cr\u00e9er HumainCroate, nous devrions dupliquer b\u00eatement (pl\u00e9onasme) le code contenu dans cette classe.<\/p>\n<h1>L&rsquo;interface<\/h1>\n<p>Les interfaces servent \u00e0 passer des contrats avec des classes, elles impliquent la m\u00eame notion de contrainte que les classes abstraites (\u00ab\u00a0Si tu veux \u00eatre comme moi, tu dois faire comme moi !\u00a0\u00bb). Mais l&rsquo;interface est un m\u00e9canisme plus simple : ce n&rsquo;est pas une classe, donc inutile de l&rsquo;instancier ou d&rsquo;en h\u00e9riter ! Puis, m\u00eame si elle peut contenir des constantes comme dans une classe abstraite (ou pas), les fonctions qu&rsquo;elle impose sont TOUJOURS en mode d&rsquo;acc\u00e8s public. Le mot cl\u00e9 pour utiliser une interface est <strong>implements<\/strong>.<\/p>\n<pre class=\"brush: php; title: ; notranslate\" title=\"\">\r\ninterface AnimalNageur {\r\n\tpublic function nager();\r\n}\r\n\r\nabstract class EtreVivant {\r\n    protected $_age = 0;\r\n\tprotected $_poids = 0;\r\n\r\n\tpublic function mourir() {\r\n\t\t$this-&gt;_cesserFonctionsVitales();\r\n\t}\r\n\r\n    abstract public function respirer();\r\n    abstract protected function _cesserFonctionsVitales();\r\n}\r\n\r\nclass EtreHumain extends EtreVivant implements AnimalNageur {\r\n    protected $_nationalite;\r\n\r\n    public function respirer() {\r\n        echo 'Par le nez et\/ou la bouche';\r\n    }\r\n\r\n    protected function _cesserFonctionsVitales() {\r\n        echo 'le coeur s\\'arr\u00eate de battre...AAAARGH';\r\n    }\r\n\r\n\tpublic function nager() {\r\n\t\techo 'Je peux aussi nager si on m\\'apprend';\r\n\t}\r\n}\r\n\r\nclass HumainFrancais extends EtreHumain {\r\n    public function __construct() {\r\n        $this-&gt;_nationalite = 'fran\u00e7ais';\r\n    }\r\n}\r\n\r\n$francais = new HumainFrancais;\r\n$francais-&gt;nager();\r\n$francais-&gt;mourir();\r\n<\/pre>\n<p>Dans cet exemple, la classe EtreHumain impl\u00e9mente l&rsquo;interface AnimalNageur, car un \u00eatre humain peut nager (je ne dis pas qu&rsquo;il <em>sait<\/em> nager&#8230;). Si elle impl\u00e9mente cette interface alors elle doit honorer le contrat qui la lie \u00e0 pr\u00e9sent avec AnimalNageur : donner \u00ab\u00a0vie\u00a0\u00bb \u00e0 la m\u00e9thode publique nager.<\/p>\n<p>Une classe peut impl\u00e9menter plusieurs interfaces :<\/p>\n<pre class=\"brush: php; title: ; notranslate\" title=\"\">\r\ninterface AnimalNageur {\r\n\tpublic function nager();\r\n}\r\n\r\ninterface AnimalCoureur {\r\n\tpublic function courir();\r\n}\r\n\r\nabstract class EtreVivant {\r\n    protected $_age = 0;\r\n\tprotected $_poids = 0;\r\n\r\n\tpublic function mourir() {\r\n\t\t$this-&gt;_cesserFonctionsVitales();\r\n\t}\r\n\r\n    abstract public function respirer();\r\n    abstract protected function _cesserFonctionsVitales();\r\n}\r\n\r\nclass EtreHumain extends EtreVivant\r\n                 implements AnimalNageur, AnimalCoureur {\r\n    protected $_nationalite;\r\n\r\n    public function respirer() {\r\n        echo 'Par le nez et\/ou la bouche';\r\n    }\r\n\r\n    protected function _cesserFonctionsVitales() {\r\n        echo 'le coeur s\\'arr\u00eate de battre...AAAARGH';\r\n    }\r\n\r\n\tpublic function nager() {\r\n\t\techo 'Je peux aussi nager si on m\\'apprends';\r\n\t}\r\n\r\n\tpublic function courir() {\r\n\t\techo 'Je passe une jambe devant l\\'autre, tr\u00e8s vite';\r\n\t}\r\n}\r\n\r\nclass HumainFrancais extends EtreHumain {\r\n    public function __construct() {\r\n        $this-&gt;_nationalite = 'fran\u00e7ais';\r\n    }\r\n}\r\n\r\n$francais = new HumainFrancais;\r\n$francais-&gt;nager();\r\n$francais-&gt;courir();\r\n$francais-&gt;mourir();\r\n<\/pre>\n<p>EtreVivant impl\u00e9mente dor\u00e9navant AnimalNageur et AnimalCoureur, il impl\u00e9mente donc l&rsquo;ensemble des fonctions impos\u00e9es par ces deux interfaces (qui ont une m\u00e9thode chacune).<\/p>\n<h2>Les interfaces et l&rsquo;h\u00e9ritage<\/h2>\n<p>Les interfaces peuvent h\u00e9riter d&rsquo;autres interfaces et la grande diff\u00e9rence par rapport aux classes c&rsquo;est qu&rsquo;elles peuvent h\u00e9riter \u00ab\u00a0en losange\u00a0\u00bb :<\/p>\n<pre class=\"brush: php; title: ; notranslate\" title=\"\">\r\ninterface A {\r\n    public function a();\r\n}\r\n\r\ninterface B {\r\n    public function b();\r\n}\r\n\r\ninterface C extends A, B {\r\n    public function c();\r\n}\r\n\r\nclass D implements C {\r\n    public function a() {\r\n    }\r\n    public function b() {\r\n    }\r\n    public function c() {\r\n    }\r\n}\r\n<\/pre>\n<p>L&rsquo;interface C \u00ab\u00a0d\u00e9rive\u00a0\u00bb les interfaces A et B, c&rsquo;est \u00e0 dire qu&rsquo;une classe qui impl\u00e9mente l&rsquo;interface C va devoir \u00e9crire a(),b() et c().<\/p>\n<h1>Faut-il privil\u00e9gier les interfaces ou les classes abstraites ?<\/h1>\n<p>Une fois de plus, il n&rsquo;y a pas de m\u00e9thode toute pr\u00eate de conception, c&rsquo;est \u00e0 vous de voir, mais t\u00e2chons tout de m\u00eame de voir les diff\u00e9rences fondamentales :<\/p>\n<ul>\n<li>une classe abstraite oblige \u00e0 la d\u00e9river pour b\u00e9n\u00e9ficier de ses fonctionnalit\u00e9s: les m\u00e9thodes \u00ab\u00a0enferm\u00e9es\u00a0\u00bb dans une classe abstraite forcent l&rsquo;h\u00e9ritage, ce qui n&rsquo;est pas n\u00e9cessairement bon<\/li>\n<li>les m\u00e9thodes \u00ab\u00a0sorties\u00a0\u00bb dans une ou des interfaces favorisent la r\u00e9-utilisabilit\u00e9 (si on enferme la m\u00e9thode courir dans EtreHumain, seuls les \u00eatres humains pourront courir&#8230;Si nous \u00e9crivons une interface AnimalCoureur avec cette m\u00e9thode, une autruche pourra l&rsquo;impl\u00e9menter et courir \u00e0 son tour, sans aboutir \u00e0 l&rsquo;ineptie qui consisterait pour Autruche \u00e0 d\u00e9river EtreHumain pour pouvoir courir)<\/li>\n<\/ul>\n<h1>R\u00e9sum\u00e9<\/h1>\n<ul>\n<li>Une classe abstraite peut contenir du code, pas une interface. Vue sous cet angle,<br \/>\nune interface est 100% abstraite, elle ne contient que des prototypes (ou signatures)<br \/>\nde fonctions publiques<\/li>\n<li>Une interface, comme une classe, peut poss\u00e9der des constantes<\/li>\n<li>Une interface s&rsquo;impl\u00e9mente, une classe s&rsquo;instancie ou se d\u00e9rive<\/li>\n<li>Une classe peut impl\u00e9menter plusieurs interfaces mais ne peut sp\u00e9cialiser qu&rsquo;une seule classe (en PHP)<\/li>\n<li>Une interface peut \u00eatre impl\u00e9ment\u00e9e par plusieurs classes<\/li>\n<li>Les m\u00e9thodes d&rsquo;une interface sont forc\u00e9ment publiques, celles d&rsquo;une classe abstraite peuvent \u00eatre de tout type, comme dans une classe normale et uniquement publiques ou prot\u00e9g\u00e9es si elles sont abstraites<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Les interfaces, comme les classes abstraites, sont des unit\u00e9s de code dont la raison d&rsquo;\u00eatre est de contraindre une classe \u00e0 impl\u00e9menter des m\u00e9thodes, c&rsquo;est \u00e0 dire \u00e0 les concr\u00e9tiser ! Nous allons voir en d\u00e9tail ces diff\u00e9rentes mani\u00e8res de contraindre les comportements de nos classes. La classe abstraite Une classe abstraite est avant tout [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0},"categories":[3],"tags":[59,62,61,60],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v19.6.1 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>PHP : classes abstraites et interfaces - La Fabrique de code - Tech blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"http:\/\/www.lafabriquedecode.com\/blog\/2013\/06\/php-classes-abstraites-et-interfaces\/\" \/>\n<meta property=\"og:locale\" content=\"fr_FR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"PHP : classes abstraites et interfaces - La Fabrique de code - Tech blog\" \/>\n<meta property=\"og:description\" content=\"Les interfaces, comme les classes abstraites, sont des unit\u00e9s de code dont la raison d&rsquo;\u00eatre est de contraindre une classe \u00e0 impl\u00e9menter des m\u00e9thodes, c&rsquo;est \u00e0 dire \u00e0 les concr\u00e9tiser ! Nous allons voir en d\u00e9tail ces diff\u00e9rentes mani\u00e8res de contraindre les comportements de nos classes. La classe abstraite Une classe abstraite est avant tout [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"http:\/\/www.lafabriquedecode.com\/blog\/2013\/06\/php-classes-abstraites-et-interfaces\/\" \/>\n<meta property=\"og:site_name\" content=\"La Fabrique de code - Tech blog\" \/>\n<meta property=\"article:published_time\" content=\"2013-06-12T08:43:20+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/www.lafabriquedecode.com\/blog\/wp-content\/uploads\/2013\/06\/connect.png\" \/>\n<meta name=\"author\" content=\"admin\" \/>\n<meta name=\"twitter:card\" content=\"summary\" \/>\n<meta name=\"twitter:creator\" content=\"@LaFabrique2Code\" \/>\n<meta name=\"twitter:site\" content=\"@LaFabrique2Code\" \/>\n<meta name=\"twitter:label1\" content=\"\u00c9crit par\" \/>\n\t<meta name=\"twitter:data1\" content=\"admin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Dur\u00e9e de lecture estim\u00e9e\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"http:\/\/www.lafabriquedecode.com\/blog\/2013\/06\/php-classes-abstraites-et-interfaces\/\",\"url\":\"http:\/\/www.lafabriquedecode.com\/blog\/2013\/06\/php-classes-abstraites-et-interfaces\/\",\"name\":\"PHP : classes abstraites et interfaces - La Fabrique de code - Tech blog\",\"isPartOf\":{\"@id\":\"http:\/\/www.lafabriquedecode.com\/blog\/#website\"},\"datePublished\":\"2013-06-12T08:43:20+00:00\",\"dateModified\":\"2013-06-12T08:43:20+00:00\",\"author\":{\"@id\":\"http:\/\/www.lafabriquedecode.com\/blog\/#\/schema\/person\/83863c048b82fd9ccf6407bddd241162\"},\"breadcrumb\":{\"@id\":\"http:\/\/www.lafabriquedecode.com\/blog\/2013\/06\/php-classes-abstraites-et-interfaces\/#breadcrumb\"},\"inLanguage\":\"fr-FR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"http:\/\/www.lafabriquedecode.com\/blog\/2013\/06\/php-classes-abstraites-et-interfaces\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"http:\/\/www.lafabriquedecode.com\/blog\/2013\/06\/php-classes-abstraites-et-interfaces\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"http:\/\/www.lafabriquedecode.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"PHP : classes abstraites et interfaces\"}]},{\"@type\":\"WebSite\",\"@id\":\"http:\/\/www.lafabriquedecode.com\/blog\/#website\",\"url\":\"http:\/\/www.lafabriquedecode.com\/blog\/\",\"name\":\"La Fabrique de code - Tech blog\",\"description\":\"PHP objet, MySQL, Design Patterns, OOP...et plus !\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"http:\/\/www.lafabriquedecode.com\/blog\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"fr-FR\"},{\"@type\":\"Person\",\"@id\":\"http:\/\/www.lafabriquedecode.com\/blog\/#\/schema\/person\/83863c048b82fd9ccf6407bddd241162\",\"name\":\"admin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"fr-FR\",\"@id\":\"http:\/\/www.lafabriquedecode.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"http:\/\/0.gravatar.com\/avatar\/fc2e1de7c8a1871b50ff9c6a6f8682a2?s=96&d=retro&r=g\",\"contentUrl\":\"http:\/\/0.gravatar.com\/avatar\/fc2e1de7c8a1871b50ff9c6a6f8682a2?s=96&d=retro&r=g\",\"caption\":\"admin\"},\"url\":\"http:\/\/www.lafabriquedecode.com\/blog\/author\/admin\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"PHP : classes abstraites et interfaces - La Fabrique de code - Tech blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"http:\/\/www.lafabriquedecode.com\/blog\/2013\/06\/php-classes-abstraites-et-interfaces\/","og_locale":"fr_FR","og_type":"article","og_title":"PHP : classes abstraites et interfaces - La Fabrique de code - Tech blog","og_description":"Les interfaces, comme les classes abstraites, sont des unit\u00e9s de code dont la raison d&rsquo;\u00eatre est de contraindre une classe \u00e0 impl\u00e9menter des m\u00e9thodes, c&rsquo;est \u00e0 dire \u00e0 les concr\u00e9tiser ! Nous allons voir en d\u00e9tail ces diff\u00e9rentes mani\u00e8res de contraindre les comportements de nos classes. La classe abstraite Une classe abstraite est avant tout [&hellip;]","og_url":"http:\/\/www.lafabriquedecode.com\/blog\/2013\/06\/php-classes-abstraites-et-interfaces\/","og_site_name":"La Fabrique de code - Tech blog","article_published_time":"2013-06-12T08:43:20+00:00","og_image":[{"url":"http:\/\/www.lafabriquedecode.com\/blog\/wp-content\/uploads\/2013\/06\/connect.png"}],"author":"admin","twitter_card":"summary","twitter_creator":"@LaFabrique2Code","twitter_site":"@LaFabrique2Code","twitter_misc":{"\u00c9crit par":"admin","Dur\u00e9e de lecture estim\u00e9e":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"http:\/\/www.lafabriquedecode.com\/blog\/2013\/06\/php-classes-abstraites-et-interfaces\/","url":"http:\/\/www.lafabriquedecode.com\/blog\/2013\/06\/php-classes-abstraites-et-interfaces\/","name":"PHP : classes abstraites et interfaces - La Fabrique de code - Tech blog","isPartOf":{"@id":"http:\/\/www.lafabriquedecode.com\/blog\/#website"},"datePublished":"2013-06-12T08:43:20+00:00","dateModified":"2013-06-12T08:43:20+00:00","author":{"@id":"http:\/\/www.lafabriquedecode.com\/blog\/#\/schema\/person\/83863c048b82fd9ccf6407bddd241162"},"breadcrumb":{"@id":"http:\/\/www.lafabriquedecode.com\/blog\/2013\/06\/php-classes-abstraites-et-interfaces\/#breadcrumb"},"inLanguage":"fr-FR","potentialAction":[{"@type":"ReadAction","target":["http:\/\/www.lafabriquedecode.com\/blog\/2013\/06\/php-classes-abstraites-et-interfaces\/"]}]},{"@type":"BreadcrumbList","@id":"http:\/\/www.lafabriquedecode.com\/blog\/2013\/06\/php-classes-abstraites-et-interfaces\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"http:\/\/www.lafabriquedecode.com\/blog\/"},{"@type":"ListItem","position":2,"name":"PHP : classes abstraites et interfaces"}]},{"@type":"WebSite","@id":"http:\/\/www.lafabriquedecode.com\/blog\/#website","url":"http:\/\/www.lafabriquedecode.com\/blog\/","name":"La Fabrique de code - Tech blog","description":"PHP objet, MySQL, Design Patterns, OOP...et plus !","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"http:\/\/www.lafabriquedecode.com\/blog\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"fr-FR"},{"@type":"Person","@id":"http:\/\/www.lafabriquedecode.com\/blog\/#\/schema\/person\/83863c048b82fd9ccf6407bddd241162","name":"admin","image":{"@type":"ImageObject","inLanguage":"fr-FR","@id":"http:\/\/www.lafabriquedecode.com\/blog\/#\/schema\/person\/image\/","url":"http:\/\/0.gravatar.com\/avatar\/fc2e1de7c8a1871b50ff9c6a6f8682a2?s=96&d=retro&r=g","contentUrl":"http:\/\/0.gravatar.com\/avatar\/fc2e1de7c8a1871b50ff9c6a6f8682a2?s=96&d=retro&r=g","caption":"admin"},"url":"http:\/\/www.lafabriquedecode.com\/blog\/author\/admin\/"}]}},"_links":{"self":[{"href":"http:\/\/www.lafabriquedecode.com\/blog\/wp-json\/wp\/v2\/posts\/569"}],"collection":[{"href":"http:\/\/www.lafabriquedecode.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.lafabriquedecode.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.lafabriquedecode.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/www.lafabriquedecode.com\/blog\/wp-json\/wp\/v2\/comments?post=569"}],"version-history":[{"count":49,"href":"http:\/\/www.lafabriquedecode.com\/blog\/wp-json\/wp\/v2\/posts\/569\/revisions"}],"predecessor-version":[{"id":1305,"href":"http:\/\/www.lafabriquedecode.com\/blog\/wp-json\/wp\/v2\/posts\/569\/revisions\/1305"}],"wp:attachment":[{"href":"http:\/\/www.lafabriquedecode.com\/blog\/wp-json\/wp\/v2\/media?parent=569"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.lafabriquedecode.com\/blog\/wp-json\/wp\/v2\/categories?post=569"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.lafabriquedecode.com\/blog\/wp-json\/wp\/v2\/tags?post=569"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}