/**
POGL : programmation objet et génie logiciel
Classes abstraites
@author Thibaut Balabonski @ Université Paris-Sud
@version 28 janvier 2019
*/
/**
Une définition de classe ordinaire est constituée :
- de déclarations d'attributs (avec éventuellement des valeurs initiales)
- de définitions de constructeurs
- de définitions de méthodes
Une /classe abstraite/ peut en outre contenir des déclarations de méthodes
non accompagnées de définitions, qu'on appelle /méthodes abstraites/. Le
caractère abstrait d'une méthode ou d'une classe doit impérativement être
indiqué, à l'aide du mot-clé [abstract].
Une classe abstraite peut être vue comme une classe "à trous", destinée à
être complétée pour former une vraie classe .
*/
abstract class A {
// Attribut ordinaire
protected int a;
/* La visibilité [protected] rend cet attribut accessible depuis une
éventuelle classe fille. */
// Constructeur ordinaire
public A(int a) {
this.a = a;
}
// Méthode ordinaire
public int getA() {
return a;
}
// Méthode abstraite
/**
On ne déclare que la signature (on dit parfois aussi le profil),
c'est-à-dire le type du résultat et les noms et types des paramètres.
On ne donne en revanche aucun code.
*/
abstract public int f(int x);
public static void main(String[] args) {
// A obj = new A(3);
/**
Il n'est pas possible de créer une instance d'une classe abstraite.
En effet, certaines des méthodes déclarées dans la classe ne sont
pas définies : on pourrait envisager un appel à une méthode définie
comme
obj.getA()
mais un appel à une méthode abstraite tel
obj.f(4)
ne pourrait être exécuté, faute de code pour [f].
Pour éviter ce genre de problème plus tard, Java restreint en amont
la création d'objets.
*/
}
}
/**
Lors de sa définition, toute classe peut être déclarée comme /étendant/ une
autre classe, ce qui est noté avec le mot-clé [extends].
Une classe B étendant une classe A possède tous les attributs et méthodes de
la classe A (on dit aussi qu'elle en /hérite/). De plus, la définition de la
classe B peut apporter de nouveaux éléments parmi notamment :
- la déclaration de nouveaux attributs
- la définition de nouvelles méthodes
- de nouvelles définitions pour des méthodes déjà définies dans A (on en
reparlera plus tard)
- des définitions pour les méthodes abstraites de A
C'est par la définition de la totalité de ses méthodes abstraites qu'on
crée une classe concrète à partir d'une classe abstraite donnée.
*/
class B extends A {
/* L'attribut [a] et la méthode [getA] existent déjà, ne surtout pas les
mentionner à nouveau (au risque de créer de nouveaux attributs ou
méthodes interférant avec ceux déjà présents). */
// Définition d'un constructeur
public B(int a) {
/* On fait appel au constructeur de la classe mère [A], qui se charge
d'initialiser l'attribut [a]. */
super(a);
}
// Définition pour la méthode abstraite [f]
/**
On répète la signature à l'identique, mais on y adjoint une définition
sous la forme habituelle d'un bloc de code.
*/
public int f(int x) {
this.a += x;
return this.a;
/* Note : si l'attribut [a] était privé dans [A] il ne serait pas
possible de faire cette mise à jour depuis la classe [B]. */
}
}
/**
Une classe [B] étendant la classe abstraite [A] peut ne pas définir toutes
les méthodes abstraites de [A]. Dans ce cas, la classe [B] hérite des
déclarations de méthodes abstraites restantes, et doit elle-même être
déclarée abstraite.
*/