Mis à jour le 08/01/2018
  • 30 heures
  • Moyenne

Ce cours est visible gratuitement en ligne.

Ce cours existe en livre papier.

Vous pouvez obtenir un certificat de réussite à l'issue de ce cours.

Vous pouvez être accompagné et mentoré par un professeur particulier par visioconférence sur ce cours.

J'ai tout compris !

L'héritage

Connectez-vous ou inscrivez-vous gratuitement pour bénéficier de toutes les fonctionnalités de ce cours !

L'héritage en POO (que ce soit en C++, Java ou autre langage utilisant la POO) est une technique très puissante et extrêmement pratique. Ce chapitre sur l'héritage est le chapitre à connaitre par cœur (ou du moins, le mieux possible). Pour être bien sûr que vous ayez compris le principe, un TP vous attend au prochain chapitre. ;)

Allez, j'arrête de vous mettre la pression, allons-y !

Notion d'héritage

Définition

Quand on parle d'héritage, c'est qu'on dit qu'une classe B hérite d'une classe A. La classe A est donc considérée comme la classe mère et la classe B est considérée comme la classe fille.

Concrètement, l'héritage, c'est quoi ?

Lorsqu'on dit que la classe B hérite de la classe A, c'est que la classe B hérite de tous les attributs et méthodes de la classe A. Si l'on déclare des méthodes dans la classe A, et qu'on crée une instance de la classe B, alors on pourra appeler n'importe quelle méthode déclarée dans la classe A du moment qu'elle est publique.

Schématiquement, une classe B héritant d'une classe A peut être représentée comme ceci (figure suivante).

Exemple d'une classe Magicien héritant d'une classe Personnage
Exemple d'une classe Magicien héritant d'une classe Personnage

Vous voyez que la classe Magicien a hérité de toutes les méthodes et d'aucun attribut de la classe Personnage. Souvenez-vous : toutes les méthodes sont publiques et tous les attributs sont privés. En fait, les attributs privés ont bien été hérités aussi, mais notre classe Magicien ne pourra s'en servir, c'est la raison pour laquelle je ne les ai pas représentés. Il n'y a que les méthodes de la classe parente qui auront accès à ces attributs. C'est comme pour le principe d'encapsulation : ici, les éléments privés sont masqués. On dit que la classe Personnage est la classe mère et que la classe Magicien est la classe fille.

Quand est-ce que je sais si telle classe doit hériter d'une autre ?

Soit deux classes A et B. Pour qu'un héritage soit possible, il faut que vous puissiez dire que A est un B. Par exemple, un magicien est un personnage, donc héritage. Un chien est un animal, donc héritage aussi. Bref, vous avez compris le principe. ;)

Procéder à un héritage

Pour procéder à un héritage (c'est-à-dire faire en sorte qu'une classe hérite des attributs et méthodes d'une autre classe), il suffit d'utiliser le mot-clé extends. Vous déclarez votre classe comme d'habitude (class MaClasse) en ajoutant extends NomDeLaClasseAHeriter comme ceci :

<?php
class Personnage // Création d'une classe simple.
{

}

class Magicien extends Personnage // Notre classe Magicien hérite des attributs et méthodes de Personnage.
{

}

Comme dans la réalité, une mère peut avoir plusieurs filles, mais une fille ne peut avoir plusieurs mères. La seule différence avec la vie réelle, c'est qu'une mère ne peut avoir une infinité de filles. :-°

Ainsi, on pourrait créer des classes MagicienGuerrierBrute, etc., qui héritent toutes de Personnage : la classe Personnage sert de modèle.

<?php
class Personnage // Création d'une classe simple.
{

}

// Toutes les classes suivantes hériteront de Personnage.

class Magicien extends Personnage
{

}

class Guerrier extends Personnage
{

}

class Brute extends Personnage
{

}

Ainsi, toutes ces nouvelles classes auront les mêmes attributs et méthodes quePersonnage. ;)

Super, tu me crées des classes qui sont exactement les mêmes qu'une autre… Très utile ! En plus, tout ce qui est privé, je n'y ai pas accès donc…

Nous sommes d'accord, si l'héritage c'était ça, ce serait le concept le plus idiot et le plus inutile de la POO. :-°

Chaque classe peut créer des attributs et méthodes qui lui seront propres, et c'est là toute la puissance de l'héritage : toutes les classes que l'on a créées plus haut peuvent avoir des attributs et méthodes en plus des attributs et méthodes hérités. Pour cela, rien de plus simple. Il vous suffit de créer des attributs et méthodes comme nous avons appris jusqu'à maintenant. Un exemple ?

<?php
class Magicien extends Personnage
{
  private $_magie; // Indique la puissance du magicien sur 100, sa capacité à produire de la magie.
  
  public function lancerUnSort($perso)
  {
    $perso->recevoirDegats($this->_magie); // On va dire que la magie du magicien représente sa force.
  }
}

Ainsi, la classe Magicien aura, en plus des attributs et méthodes hérités, un attribut $magie et une méthode lancerUnSort.

Redéfinir les méthodes

On vient de créer une classe Magicien héritant de toutes les méthodes de la classe Personnage. Que diriez-vous si l'on pouvait réécrire certaines méthodes, afin de modifier leur comportement ? Pour cela, il vous suffit de déclarer à nouveau la méthode et d'écrire ce que bon vous semble à l'intérieur.

Un problème se pose pourtant. Si vous voulez accéder à un attribut de la classe parente pour le modifier, vous ne pourrez pas car notre classe Magicien n'a pas accès aux attributs de sa classe mère Personnage puisqu'ils sont tous privés.

Nous allons maintenant essayer de redéfinir la méthode gagnerExperience afin de modifier l'attribut stockant la magie (admettons $_magie) lorsque, justement, on gagne de l'expérience. Problème : si on la réécrit, nous écrasons toutes les instructions présentes dans la méthode de la classe parente (Personnage), ce qui aura pour effet de ne pas faire gagner d'expérience à notre magicien mais juste de lui augmenter sa magie. Solution : appeler la méthode gagnerExperience de la classe parente, puis ensuite ajouter les instructions modifiant la magie.

Il suffit pour cela d'utiliser le mot-clé parent suivi du symbole double deux points, suivi lui-même du nom de la méthode à appeler.

<?php
class Magicien extends Personnage
{
  private $_magie; // Indique la puissance du magicien sur 100, sa capacité à produire de la magie.
  
  public function lancerUnSort($perso)
  {
    $perso->recevoirDegats($this->_magie); // On va dire que la magie du magicien représente sa force.
  }
  
  public function gagnerExperience()
  {
    // On appelle la méthode gagnerExperience() de la classe parente
    parent::gagnerExperience();
    
    if ($this->_magie < 100)
    {
      $this->_magie += 10;
    }
  }
}

Notez que si la méthode parente retourne une valeur, vous pouvez la récupérer comme si vous appeliez une méthode normalement. Exemple :

<?php
class A
{
  public function test()
  {
    return 'test';
  }
}

class B extends A
{
  public function test()
  {
    $retour = parent::test();
    
    echo $retour;
  }
}

$b = new B;
$b->test(); // Affiche "test"

Comme vous pouvez le constater, j'ai fait appel aux getters et setters correspondant à l'attribut $_magie. Pourquoi ? Car les classes enfant n'ont pas accès aux éléments privés, il fallait donc que la classe parente le fasse pour moi ! Il n'y a que les méthodes de la classe parente non réécrites qui ont accès aux éléments privés. À partir du moment où l'on réécrit une méthode de la classe parente, la méthode appartient à la classe fille et n'a donc plus accès aux éléments privés.

Héritez à l'infini !

Toute classe en POO peut être héritée si elle ne spécifie pas le contraire, vraiment toutes. Vous pouvez ainsi reproduire un arbre réel avec autant de classes héritant les unes des autres que vous le souhaitez.

Pour reprendre l'exemple du magicien dans le cours sur la POO en C++ de M@teo21, on peut créer deux autres classes MagicienBlanc et MagicienNoir qui héritent toutes les deux de Magicien. Exemple :

<?php
class Personnage // Classe Personnage de base.
{

}

class Magicien extends Personnage // Classe Magicien héritant de Personnage.
{

}

class MagicienBlanc extends Magicien // Classe MagicienBlanc héritant de Magicien.
{

}

class MagicienNoir extends Magicien // Classe MagicienNoir héritant de Magicien.
{

}

Et un petit schéma qui reproduit ce code (figure suivante).

Exemple d'un héritage multiple
Exemple d'un héritage multiple

Ainsi, les classes MagicienBlanc et MagicienNoir hériteront de tous les attributs et de toutes les méthodes des classes Magicien et Personnage. ;)

Un nouveau type de visibilité : protected

Je vais à présent vous présenter le dernier type de visibilité existant en POO : il s'agit de protected. Ce type de visibilité est, au niveau restrictif, à placer entre public et private.

Je vous rappelle brièvement les rôles de ces deux portées de visibilité :

  • Public : ce type de visibilité nous laisse beaucoup de liberté. On peut accéder à l'attribut ou à la méthode de n'importe où. Toute classe fille aura accès aux éléments publics.

  • Private : ce type est celui qui nous laisse le moins de liberté. On ne peut accéder à l'attribut ou à la méthode que depuis l'intérieur de la classe qui l'a créé. Toute classe fille n'aura pas accès aux éléments privés.

Le type de visibilité protected est en fait une petite modification du type private : il a exactement les mêmes effets que private, à l'exception que toute classe fille aura accès aux éléments protégés.

Exemple :

<?php
class ClasseMere
{
  protected $attributProtege;
  private $_attributPrive;
  
  public function __construct()
  {
    $this->attributProtege = 'Hello world !';
    $this->_attributPrive = 'Bonjour tout le monde !';
  }
}

class ClasseFille extends ClasseMere
{
  public function afficherAttributs()
  {
    echo $this->attributProtege; // L'attribut est protégé, on a donc accès à celui-ci.
    echo $this->_attributPrive; // L'attribut est privé, on n'a pas accès celui-ci, donc rien ne s'affichera (mis à part une notice si vous les avez activées).
  }
}

$obj = new ClasseFille;

echo $obj->attributProtege; // Erreur fatale.
echo $obj->_attributPrive; // Rien ne s'affiche (ou une notice si vous les avez activées).

$obj->afficherAttributs(); // Affiche « Hello world ! » suivi de rien du tout ou d'une notice si vous les avez activées.

Comme vous pouvez le constater, il n'y a pas d'underscores précédant les noms d'éléments protégés. C'est encore une fois la notation PEAR qui nous dit que les noms d'éléments protégés ne sont pas précédés de ce caractère. ;)

Et pour le principe d'encapsulation, j'utilise quoi ? private ou protected ?

La portée private est, selon moi, bien trop restrictive et contraignante. Elle empêche toute classe enfant d'accéder aux attributs et méthodes privées alors que cette dernière en a souvent besoin. De manière générale, je vous conseille donc de toujours mettre protected au lieu de private, à moins que vous teniez absolument à ce que la classe enfant ne puisse y avoir accès (utile si vous comptez partager votre classe).

Imposer des contraintes

Il est possible de mettre en place des contraintes. On parlera alors d'abstraction ou de finalisation suivant la contrainte instaurée.

Abstraction

Classes abstraites

On a vu jusqu'à maintenant que l'on pouvait instancier n'importe quelle classe afin de pouvoir exploiter ses méthodes. On va maintenant découvrir comment empêcher quiconque d'instancier telle classe.

Mais à quoi ça sert de créer une classe si on ne peut pas s'en servir ?

On ne pourra pas se servir directement de la classe. La seule façon d'exploiter ses méthodes est de créer une classe héritant de la classe abstraite.

Vous vous demandez sans doute à quoi cela peut bien servir. L'exemple que je vais prendre est celui du personnage et de ses classes filles. Dans ce que nous venons de faire, nous ne créerons jamais d'objet Personnage, mais uniquement des objets MagicienGuerrierBrute, etc. En effet, à quoi cela nous servirait d'instancier la classe Personnage si notre but est de créer un tel type de personnage ?

Nous allons donc considérer la classe Personnage comme étant une classe modèle dont toute classe fille possédera les méthodes et attributs.

Pour déclarer une classe abstraite, il suffit de faire précéder le mot-clé class du mot-clé abstract comme ceci :

<?php
abstract class Personnage // Notre classe Personnage est abstraite.
{

}

class Magicien extends Personnage // Création d'une classe Magicien héritant de la classe Personnage.
{

}

$magicien = new Magicien; // Tout va bien, la classe Magicien n'est pas abstraite.
$perso = new Personnage; // Erreur fatale car on instancie une classe abstraite.

Simple et court à retenir, il suffit juste de se souvenir où l'on doit le placer. ;)

Ainsi, si vous essayez de créer une instance de la classe Personnage, une erreur fatale sera levée. Ceci nous garantit que l'on ne créera jamais d'objet Personnage (suite à une étourderie par exemple).

Méthodes abstraites

Si vous décidez de rendre une méthode abstraite en plaçant le mot-clé abstract juste avant la visibilité de la méthode, vous forcerez toutes les classes filles à écrire cette méthode. Si tel n'est pas le cas, une erreur fatale sera levée. Puisque l'on force la classe fille à écrire la méthode, on ne doit spécifier aucune instruction dans la méthode, on déclarera juste son prototype (visibilité + function + nomDeLaMethode + parenthèses avec ou sans paramètres + point-virgule).

<?php
abstract class Personnage
{
  // On va forcer toute classe fille à écrire cette méthode car chaque personnage frappe différemment.
  abstract public function frapper(Personnage $perso);
  
  // Cette méthode n'aura pas besoin d'être réécrite.
  public function recevoirDegats()
  {
    // Instructions.
  }
}

class Magicien extends Personnage
{
  // On écrit la méthode « frapper » du même type de visibilité que la méthode abstraite « frapper » de la classe mère.
  public function frapper(Personnage $perso)
  {
    // Instructions.
  }
}

Finalisation

Classes finales

Le concept des classes et méthodes finales est exactement l'inverse du concept d'abstraction. Si une classe est finale, vous ne pourrez pas créer de classe fille héritant de cette classe.

Pour ma part, je ne rends jamais mes classes finales (au même titre que, à quelques exceptions près, je mets toujours mes attributs en protected) pour me laisser la liberté d'hériter de n'importe quelle classe.

Pour déclarer une classe finale, vous devez placer le mot-clé final juste avant le mot-clé class, comme abstract.

<?php
// Classe abstraite servant de modèle.

abstract class Personnage
{

}

// Classe finale, on ne pourra créer de classe héritant de Guerrier.

final class Guerrier extends Personnage
{

}

// Erreur fatale, car notre classe hérite d'une classe finale.

class GentilGuerrier extends Guerrier
{

}
Méthodes finales

Si vous déclarez une méthode finale, toute classe fille de la classe comportant cette méthode finale héritera de cette méthode mais ne pourra la redéfinir. Si vous déclarez votre méthode recevoirDegats en tant que méthode finale, vous ne pourrez la redéfinir.

<?php
abstract class Personnage
{
  // Méthode normale.
  
  public function frapper(Personnage $perso)
  {
    // Instructions.
  }
  
  // Méthode finale.
  
  final public function recevoirDegats()
  {
    // Instructions.
  }
}

class Guerrier extends Personnage
{
  // Aucun problème.
  
  public function frapper(Personnage $perso)
  {
    // Instructions.
  }
  
  // Erreur fatale car cette méthode est finale dans la classe parente.
  
  public function recevoirDegats()
  {
    // Instructions.
  }
}

Résolution statique à la volée

Cette section va vous montrer une possibilité intéressante de la POO en PHP : la résolution statique à la volée. C'est une notion un peu complexe à comprendre au premier abord, alors n'hésitez pas à relire plusieurs fois.

Effectuons d'abord un petit flash-back sur self::. Vous vous souvenez à quoi il sert ? À appeler un attribut, une méthode statique ou une constante de la classe dans laquelle est contenu self::. Ainsi, si vous testez ce code :

<?php
class Mere
{
  public static function lancerLeTest()
  {
    self::quiEstCe();
  }
  
  public static function quiEstCe()
  {
    echo 'Je suis la classe <strong>Mere</strong> !';
  }
}

class Enfant extends Mere
{
  public static function quiEstCe()
  {
    echo 'Je suis la classe <strong>Enfant</strong> !';
  }
}

Enfant::lancerLeTest();

À l'écran s'affichera :

Résultat affiché par le script
Résultat affiché par le script

Mais qu'est-ce qu'il s'est passé ???

  • appel de la méthode lancerLeTest de la classe Enfant ;

  • la méthode n'a pas été réécrite, on va donc « chercher » la méthode lancerLeTest de la classe mère ;

  • appel de la méthode quiEstCe de la classeMere.

Pourquoi c'est la méthode quiEstCe de la classe parente qui a été appelée ? Pourquoi pas celle de la classe fille puisqu'elle a été récrite ?

Tout simplement parce que self:: fait appel à la méthode statique de la classe dans laquelle est contenu self::, donc de la classe parente. ;)

Et la résolution statique à la volée dans tout ça ?

Tout tourne autour de l'utilisation de static::static:: a exactement le même effet que self::, à l'exception près que static::appelle l'élément de la classe qui est appelée pendant l'exécution. C'est-à-dire que si j'appelle la méthode lancerLeTest depuis la classe Enfant et que dans cette méthode j'utilise static:: au lieu de self::, c'est la méthode quiEstCe de la classe Enfant qui sera appelée et non de la classe Mere !

<?php
class Mere
{
  public static function lancerLeTest()
  {
    static::quiEstCe();
  }
  
  public function quiEstCe()
  {
    echo 'Je suis la classe <strong>Mere</strong> !';
  }
}

class Enfant extends Mere
{
  public static function quiEstCe()
  {
    echo 'Je suis la classe <strong>Enfant</strong> !';
  }
}

Enfant::lancerLeTest();

Ce qui donnera :

Résultat affiché par le script
Résultat affiché par le script
<?php
class Mere
{
  public function lancerLeTest()
  {
    static::quiEstCe();
  }
  
  public function quiEstCe()
  {
    echo 'Je suis la classe « Mere » !';
  }
}

class Enfant extends Mere
{
  public function quiEstCe()
  {
    echo 'Je suis la classe « Enfant » !';
  }
}

$e = new Enfant;
$e->lancerLeTest();

Cas complexes

Au premier abord, vous n'avez peut-être pas tout compris. Si tel est le cas, ne lisez pas la suite cela risquerait de vous embrouiller davantage. Prenez bien le temps de comprendre ce qui est écrit plus haut puis vous pourrez continuer. ;)

Comme le spécifie le titre, il y a quelques cas complexes (des pièges en quelque sorte). Imaginons trois classes A, B et C qui héritent chacune d'une autre (A est la grand-mère, B la mère et C la fille). En PHP, on dirait plutôt :

<?php
class A
{

}

class B extends A
{

}

class C extends B
{

}

Nous allons implémenter dans chacune des classes une méthode qui aura pour rôle d'afficher le nom de la classe pour pouvoir effectuer quelques tests.

<?php
class A
{
  public function quiEstCe()
  {
    echo 'A';
  }
}

class B extends A
{
  public function quiEstCe()
  {
    echo 'B';
  }
}

class C extends B
{
  public function quiEstCe()
  {
    echo 'C';
  }
}

Créons une méthode de test dans la classe B. Pourquoi dans cette classe ? Parce qu'elle hérite de A et est héritée par C, son cas est donc intéressant à étudier.

Appelons maintenant cette méthode depuis la classe C dans un contexte statique (nul besoin de créer d'objet, mais ça marche tout aussi bien ;) ).

<?php
class A
{
  public function quiEstCe()
  {
    echo 'A';
  }
}

class B extends A
{
  public static function test()
  {
  
  }
  
  public function quiEstCe()
  {
    echo 'B';
  }
}

class C extends B
{
  public function quiEstCe()
  {
    echo 'C';
  }
}

C::test();

Plaçons un peu de code dans cette méthode, sinon ce n'est pas drôle.

Nous allons essayer d'appeler la méthode parentequiEstCe. Là, il n'y a pas de piège, pas de résolution statique à la volée, donc à l'écran s'affichera « A » :

<?php
class A
{
  public function quiEstCe()
  {
    echo 'A';
  }
}

class B extends A
{
  public static function test()
  {
    parent::quiEstCe();
  }
  
  public function quiEstCe()
  {
    echo 'B';
  }
}

class C extends B
{
  public function quiEstCe()
  {
    echo 'C';
  }
}

C::test();

Maintenant, créons une méthode dans la classe A qui sera chargée d'appeler la méthodequiEstCeavecstatic::. Là, si vous savez ce qui va s'afficher, vous avez tout compris ! ;)

<?php
class A
{
  public function appelerQuiEstCe()
  {
    static::quiEstCe();
  }
  
  public function quiEstCe()
  {
    echo 'A';
  }
}

class B extends A
{
  public static function test()
  {
    parent::appelerQuiEstCe();
  }
  
  public function quiEstCe()
  {
    echo 'B';
  }
}

class C extends B
{
  public function quiEstCe()
  {
    echo 'C';
  }
}

C::test();
?>

Alors ? Vous avez une petite idée ? À l'écran s'affichera… C ! Décortiquons ce qui s'est passé :

  • Appel de la méthodetestde la classeC;

  • la méthode n'a pas été réécrite, on appelle donc la méthodetestde la classeB;

  • on appelle maintenant la méthodeappelerQuiEstCede la classeA(avecparent::) ;

  • résolution statique à la volée : on appelle la méthodequiEstCede la classe qui a appelé la méthodeappelerQuiEstCe;

  • la méthodequiEstCede la classeCest donc appelée car c'est depuis la classeCqu'on a appelé la méthodetest.

C'est très compliqué mais fondamental à comprendre. :p

Remplaçons maintenantparent::parself:::

<?php
class A
{
  public function appelerQuiEstCe()
  {
    static::quiEstCe();
  }
  
  public function quiEstCe()
  {
    echo 'A';
  }
}

class B extends A
{
  public static function test()
  {
    self::appelerQuiEstCe();
  }
  
  public function quiEstCe()
  {
    echo 'B';
  }
}

class C extends B
{
  public function quiEstCe()
  {
    echo 'C';
  }
}

C::test();

Et là, qu'est-ce qui s'affiche à l'écran ? Et bien toujours C ! Le principe est exactement le même que le code plus haut.

<?php
class A
{
  public static function appelerQuiEstCe()
  {
    static::quiEstCe();
  }
  
  public function quiEstCe()
  {
    echo 'A';
  }
}

class B extends A
{
  public static function test()
  {
    // On appelle « appelerQuiEstCe » de la classe « A » normalement.
    A::appelerQuiEstCe();
  }
  
  public function quiEstCe()
  {
    echo 'B';
  }
}

class C extends B
{
  public function quiEstCe()
  {
    echo 'C';
  }
}

C::test();

Utilisation de static:: dans un contexte non statique

L'utilisation destatic::dans un contexte non statique se fait de la même façon que dans un contexte statique. Je vais prendre l'exemple de la documentation pour illustrer mes propos :

<?php
class TestParent
{
  public function __construct()
  {
    static::qui();
  }
  
  public static function qui()
  {
    echo 'TestParent';
  }
}

class TestChild extends TestParent
{
  public function __construct()
  {
    static::qui();
  }
  
  public function test()
  {
    $o = new TestParent();
  }
  
  public static function qui()
  {
    echo 'TestChild';
  }
}

$o = new TestChild;
$o->test();

À l'écran s'affichera « TestChild » suivi de « TestParent ». Je vous explique ce qui s'est passé si vous n'avez pas tout suivi :

  • Création d'une instance de la classeTestChild;

  • appel de la méthodequide la classeTestChildpuisque c'est la méthode__constructde la classeTestChildqui a été appelée ;

  • appel de la méthodetestde la classeTestChild;

  • création d'une instance de la classeTestParent;

  • appel de la méthodequide la classeTestParentpuisque c'est la méthode__constructde cette classe qui a été appelée.

Ouf ! Enfin terminé ! :)

N'hésitez pas à le relire autant de fois que nécessaire afin de bien comprendre cette notion d'héritage et toutes les possibilités que ce concept vous offre. Ne soyez pas pressés de continuer si vous n'avez pas tout compris, sinon vous allez vous planter au TP.

En résumé

  • Nous pouvons parler d'héritage entre une classe A et une classe B si et seulement si nous pouvons dire « B est un A » (dans ce cas-là, B hérite de A).

  • Une classe héritant d'une autre a accès à tous ses attributs et méthodes publics et protégés.

  • La visibilitéprotectedest équivalente à la visibilitéprivateà la différence près qu'un élément protégé est accessible par les classes filles, contrairement aux éléments privés.

  • Il est possible d'interdire l'instanciation d'une classe grâce au mot-cléabstract(utile pour poser un modèle de base commun à plusieurs classes) et l'héritage d'une classe grâce au mot-cléfinal.

  • Il est possible d'obliger ses classes filles à implémenter une méthode grâce au mot-cléabstractet de leur interdire la réécriture d'une méthode grâce au mot-cléfinal.

  • La résolution statique à la volée permet de savoir quelle classe a été initialement appelée afin d'invoquer des méthodes ou accéder à des attributs de la classe appelée.

Vous êtes demandeur d'emploi ?
Sans diplôme post-bac ?

Devenez Développeur web junior

Je postule
Formation
en ligne
Financée
à 100%
Exemple de certificat de réussite
Exemple de certificat de réussite