Programmation Orientée Objet en JAVA
Classes abstraites et Interfaces
Principe fondamental de la POO
- Les classes abstraites et les interfaces masquent les détails d’implémentation tout en exposant les fonctionnalités essentielles.
- Ces concepts facilitent la modélisation et permettent de créer des modèles ou des schémas pour les classes concrètes.
- Ils améliorent également la réutilisabilité et la maintenance en facilitant la factorisation du code et son évolution.
Classes abstraites
- Définition du terme 'abstract' : signifie qu’il n’y a pas d’implémentation.
- Méthode abstraite : méthode qui ne contient pas de code.
- Déclaration :
abstract typeRetour nomMethodes([args]);
Caractéristiques des classes abstraites
- Une classe abstraite ne peut pas être instanciée directement.
- Une classe contenant une méthode abstraite doit obligatoirement être abstraite, mais une classe abstraite n’a pas obligatoirement de méthodes abstraites.
- Toute classe qui hérite (ou étend) d’une classe abstraite doit obligatoirement implémenter l’ensemble des méthodes abstraites définies dans celle-ci.
Fonctionnalités des classes abstraites
- Servent de modèle pour créer des classes dérivées.
- Définissent des comportements communs et des attributs partagés.
- Utilisent le mot-clé
abstract lors de la déclaration.- Syntaxe :
abstract class NomDeLaClasse { // corps de la classe: }
Exemple de structure de classes abstraites
- Classe abstraite Figures :
abstract class Figures {
protected double x, y;
public Figures(double x, double y) {
this.x = x;
this.y = y;
}
public abstract void dessiner();
public abstract double calculerSurface();
}
class Disque extends Figures {
private double rayon;
public Disque(double x, double y, double rayon) {
super(x, y);
this.rayon = rayon;
}
public void dessiner() {
System.out.println("Dessiner un disque de rayon " + rayon);
}
public double calculerSurface() {
return Math.PI * rayon * rayon;
}
}
class Rectangle extends Figures {
private double longueur, largeur;
public Rectangle(double x, double y, double longueur, double largeur) {
super(x, y);
this.longueur = longueur;
this.largeur = largeur;
}
@Override
public void dessiner() {
System.out.println("Dessiner un rectangle de " + longueur + " x " + largeur);
}
@Override
public double calculerSurface() {
return longueur * largeur;
}
}
class Triangle extends Figures {
private double base, hauteur;
public Triangle(double x, double y, double base, double hauteur) {
super(x, y);
this.base = base;
this.hauteur = hauteur;
}
@Override
public void dessiner() {
System.out.println("Dessiner un triangle de base " + base + " et hauteur " + hauteur);
}
@Override
public double calculerSurface() {
return (base * hauteur) / 2;
}
}
class Carre extends Figures {
private double cote;
public Carre(double x, double y, double cote) {
super(x, y);
this.cote = cote;
}
@Override
public void dessiner() {
System.out.println("Dessiner un carré de côté " + cote);
}
@Override
public double calculerSurface() {
return cote * cote;
}
}
- Règle d'implémentation : Toutes les méthodes abstraites doivent être implémentées. Si une méthode n'est pas implémentée, la classe doit être déclarée abstraite. Les méthodes concrètes peuvent être redéfinies si nécessaire, utilisant l'annotation
@Override pour indiquer la redéfinition. La nouvelle classe devient concrète et peut être instanciée.
Interfaces
- Définition d'une interface : Il s'agit d'un contrat qui définit un ensemble de méthodes qu’une classe doit implémenter.
- Abstraction totale : 100% abstraite, sans aucun code implémenté.
- Héritage multiple : Une classe peut implémenter plusieurs interfaces.
- Structure d'une interface : Contient uniquement des constantes et des prototypes de méthodes.
- Syntaxe :
interface NomDInterface { // corps de l’interface : typeAccès final type nomCconstante = val; typeAccès typeRetour nomMethodes([args]); }
Caractéristiques des méthodes et variables dans une interface
- Les méthodes dans une interface sont publiques et abstraites par défaut.
- Les variables dans une interface sont publiques, statiques et finales par défaut.
- Le mot-clé
implements permet de signifier l’implémentation d'une interface par une classe. - Règle d'implémentation : Les méthodes des interfaces implémentées doivent être redéfinies dans la classe.
- Exemple de syntaxe :
class NomDeLaClasse implements NomDInterface1, NomDInterface2, NomDInterface3 { // corps de la classe }
Exemple d'implémentation d'une interface
interface AfficheType {
public void afficher();
}
class Personne implements AfficheType {
public void afficher() {
System.out.println("Je suis une personne");
}
}
class Voiture implements AfficheType {
public void afficher() {
System.out.println("Je suis une voiture");
}
}
Héritage des interfaces
- Une classe peut implémenter plusieurs interfaces mais ne peut étendre qu'une seule classe à la fois.
- Exemple d'héritage à la fois de classe et d'interfaces :
class NomDeLaClasse extends MaClasse implements NomDInterface1, NomDInterface2, NomDInterface3 { // corps de la classe }
- Rappel sur l'héritage : Il n'y a pas d'héritage multiple en Java, une classe ne peut être l'extension que d'une seule classe, mais les interfaces permettent de mettre en œuvre un mécanisme de remplacement.
Précautions avec les interfaces
- Il est crucial de ne pas modifier une interface qui est déjà utilisée. Cela pourrait exiger de reprendre le code de toutes les classes qui implémentent cette interface.
Différences entre Classe abstraite et Interface
- Classe abstraite : Peut posséder des attributs, avoir des méthodes avec une implémentation, utilise l’héritage classique.
- Interface : Ne possède pas d'attributs (sauf constantes), ni constructeurs, ni méthodes implantées. Peut implanter plusieurs interfaces dans une classe.
- Choisissez entre classe abstraite et interface en fonction des besoins du problème.
Manipulation des chaînes en Java
Déclaration de la classe prédéfinie String
- Exemples de déclaration :
String e = ""; // Une chaine vide
String chaine = "Hello";
String chaine = new String("Hello");
String porte = "Porte";
String str = "Feuille";
String chaine = porte + str; // chaine vaut PorteFeuille (sans espace)
String rate = "PG" + 13; // rate vaut PG13
Propriétés et manipulation des chaînes
String chaine = "Hello";
int n = chaine.length(); // donne n = 5
- Extraire une sous-chaîne : Utilisation de la méthode substring.
- Deux versions :
myString.substring(debut)myString.substring(debut, fin)- Indices :
debut : inclusif,fin : exclusif.- Exemple :
chaine = chaine.substring(0, 3) + "p!";
Modifications des chaînes
- Bien que le contenu d'une chaîne ne puisse pas être modifié, on peut effectuer des conversions en créant de nouvelles chaînes :
- Méthodes utiles :
toLowerCase : chaîne en minuscules.toUpperCase : chaîne en majuscules.trim : nouvelle chaîne sans espaces au début ou à la fin.replace(oldChar, newChar) : remplace tous les caractères oldChar par newChar.
Comparaison des chaînes
chaine1.compareTo(chaine2);
- Retourne:
0 si les deux chaînes sont égales,- Valeur négative si chaine1 est plus petite que chaine2,
- Valeur positive si chaine2 est plus petite que chaine1.
- Comparaison égale :
chaine.equals("Bonjour") retournera true si chaine est égale à «Bonjour». chaine.equalsIgnoreCase("BonJour") : compare sans tenir compte de la casse.- Ne pas utiliser les opérateurs
>, >=, <, <= et == pour la comparaison de chaînes.
Méthodes de recherche dans les chaînes
int indexOf (int c) : indice du caractère c dans la chaîne; retourne -1 s’il n’existe pas.int indexOf (int c, int n) : indice du caractère c en partant de l’indice n.int indexOf (String s) : indice de la sous-chaîne s.int indexOf (String s, int n) : indice de s en partant d’un indice n.int lastIndexOf (int c) : indice du dernier caractère c.int lastIndexOf (char c, int i) : indice du dernier caractère en partant de la fin et d’un indice.int lastIndexOf (String) : indice de la dernière sous-chaîne.int lastIndexOf (String s, int i) : indice de la dernière sous-chaîne en partant d’un indice.String replace (char c1, char c2) : crée une nouvelle chaîne en remplaçant c1 par c2.boolean startsWith (String s) : teste si la chaîne commence par s.boolean startsWith (String s, int n) : teste si la chaîne commence par s en partant de l’indice n.boolean endsWith (String s) : teste si la chaîne se termine par s.String trim() : enlève les espaces en début et fin de chaîne.
Tableaux
Définition des tableaux
- Un tableau est une structure de données contenant plusieurs éléments tous du même type. Le type des éléments peut être un type primitif ou une classe.
- Les tableaux doivent être déclarés comme tous les objets. Lors de la définition, les
[] spécifient qu’il s’agit d’un tableau :- Exemples de déclaration :
int tabInt[];char[] tabChar;Point tabPoints[];
- Un tableau peut être initialisé :
int[] tabInt = { 1, 2, 3, 4};char tabChar[] = {'a', 'b', 'c'};
Allocations et propriétés des tableaux
- Pour allouer de l’espace au tableau, utilisez
new :tabInt = new int[10];tabChar = new char[15];Point tabPoints[]= new Point[5];
- Un tableau possède un attribut
length qui indique sa longueur (le nombre d’éléments) :tabInt.length // vaut 10tabChar.length // vaut 15
Tableaux multidimensionnels
- Un tableau à deux dimensions est un tableau de tableaux :
int tab[][] = new int[5][10];
- Un tableau à trois dimensions :
char[][][] tabChar = new char[5][10][20];
- On peut créer des tableaux de dimensions multiples, avec des initialisations diverses :
int t[][] = {{1, 2, 3}, {4, 5, 6}};
Flexibilité des dimensions des tableaux
- Toutes les lignes d’un tableau à 2 dimensions n'ont pas forcément le même nombre d’éléments :
int t2[][] = new int[5][];
for(int i = 0; i < t2.length; ++i) {
t2[i] = new int[i + 1];
}
Questions
- Questions ouvertes à discuter ou à approfondir sur les thèmes abordés.
IGA
- Réservé à une série de questions ou des exercices pratiques liés au contenu précédent.