ntro.ca

        • Contrats de classe
        • Liens utiles
        • Calendrier
        • Calendrier groupe 2
        • Calendrier groupes 1, 3
        • Structure du cours
        • Évaluations
        • Matériel à se procurer
        • Les profs
          • Marc-Olivier Tremblay
          • Mathieu Bergeron
        • Module 1.1: installation + trier des cartes
        • Module 1.2: rappels POO
        • Module 1.3: tableau d'objets
        • Examen 1
        • Module 2.1: données JSON
        • Module 2.2: données en Java
        • Module 2.3: récursivité
        • Examen 2
        • Module 3.1: structure générique
        • Module 3.2: efficacité (1)
        • Module 3.3: efficacité (2)
        • Examen 3
        • Module 4.1: liste naïve
        • Module 4.2: liste par tableau
        • Module 4.3: liste chaînée
        • Examen 4
        • Module 5.1: mappage naïf
        • Module 5.2: mappage par hachage
        • Module 5.3: mappage par arbre
        • Examen 5
        • Équipes
          • Horaire groupe 1
          • Horaire groupe 2
          • Horaire groupe 3
          • Groupe 1
          • Groupe 2
          • Groupe 3
        • Projets vedettes 2022
        • Projets vedettes 2023
        • Projets vedettes 2024
        • Projets vedettes 2025
        • Survol
        • Structure
        • Calendrier
        • Calendrier des séances
        • Évaluations
        • Exemples de jeu
        • Exemples de pages
        • Réponses à vos questions
        • Module 1: créer le projet
        • Module 2: concevoir l'application
        • Module 3: vues NtroFx
        • Module 4: modèle et navigation
        • Module 5: ajouter le dorsal, modifier le modèle
        • Module 7: améliorer l'affichage
        • Module 8: jeu en 2d
        • Module 9: client/serveur
        • Module 10: plusieurs instances du même modèle
        • TP1
        • Examen 1
        • TP2
        • Examen 2
        • Projet de fin de session
        • Calendrier
        • Structure du cours
        • Évaluations
        • Contrat de classe
        • Le prof
        • 01: Windows et Word
          • Astuces et raccourcis
        • 02: Word
        • 03: Word
          • Exercice Word: insertion d'éléments spéciaux
          • Exercice Word: tableaux
        • 04: Word
          • Exercice Word: références
          • TP01: Word (15%)
        • 05: PowerPoint
          • TP02: PowerPoint (10%)
        • 06: Examen Word (20%)
        • 07: Excel
        • 08: Excel
        • 09: Excel
          • TP03: Excel (15%)
        • 10: Excel
        • 11: Examen Excel (20%)
        • 12: Access
        • 13: Access
        • 14: Access
        • 15: Examen Access
      • Sondage H2023 (dept. info)
      • Vision H2023 (dept. info)
      • P1) exercices interactifs de lecture
      • P2) transition Excel vers Python
        • Atelier 2: un exemple
      • Jquery
      • Jquery Ui
      • Point de vue sur l'IA
    Théorie 1.2.4: interface, classe abstraite
    • Théorie 1.2.4: interface, classe abstraite
      • Interface
      • Classe abstraite
      • Impossible d’instancier une interface ou une classe abstraite
      • Quand utiliser une interface?
      • Interface et polymorphisme
      • Quand utiliser une classe abtraite?
      • Pourquoi ne pas toujours utiliser une classe abstraite?

    Théorie 1.2.4: interface, classe abstraite #

    • On a vu que extends et implements peuvent spécifier un contrat:

      • une liste de méthodes qu’il faut implanter
    • P.ex. pour extends:

    • P.ex. pour implements:
    • Vous avez déjà rempli ces contrats dans les tutoriels et les ateliers

    • Maintenant, pour créer vos propres contrats, il faut créer soit:

      • une classe abstraite dans le cas de extends
      • une interface dans le cas de implements

    Interface #

    • L’interface est le contrat le plus simple

    • Il s’agit exclusivement de signatures de méthodes publiques

    • L’interface ne contient jamais le code d’une méthode

    • P.ex. voici deux interfaces:

    public interface Rouleur {
    	
    	// public par défaut!
    	void rouler(double kilometres);  
    
    }
    
    public interface Formateur {
    	
    	String formater();
        String formaterEnHtml();
    }
    
    • Pour implanter l’interface Rouleur, il faut obligatoirement implanter la méthode rouler
    public class MonRouleur implements Rouleur {
    	
    	@Override
    	public void rouler(double kilometres){
    	//public!
    
    	}
    }
    
    • Pour implanter l’interface Formateur, il faut obligatoirement implanter deux méthodes:
    public class MonFormateur implements Formateur {
    	
    	@Override
    	public String formater(){
    	//public!
    	
    	    return null;
    	}
    
    	@Override
        public String formaterEnHtml(){
    	//public!
    	
            return null;
        }
    }
    
    • NOTE: le contrat concerne uniquement la signature et non le code de la méthode

    Classe abstraite #

    • La classe abstraite est plus flexible

    • Elle implante certaines méthodes:

         //abstract!
    public abstract class Atelier {
    	
    	public boolean isAProviderMethod(Method method) {
    		return method.getName().startsWith("fournir");
    	}
    
    	public void valider() {
    		validateTestCases();
    
    		launchApp();
    		
    		Validator.validate(this);
    	}
    
    • Alors que d’autres sont abstraites et seulement la signature est spécifiée:
                //abstract!
    	protected abstract void executer();
    	protected abstract boolean siExecutable();
    
    • Au complet ça donne:
         //abstract!
    public abstract class Atelier {
    	
    	public boolean isAProviderMethod(Method method) {
    		return method.getName().startsWith("fournir");
    	}
    
    	public void valider() {
    		validateTestCases();
    
    		launchApp();
    		
    		Validator.validate(this);
    	}
    	
                //abstract!
    	protected abstract void executer();
    	protected abstract boolean siExecutable();
    }
    
    • Quand on hérite de Atelier il faut obligatoirement implanter deux méthodes:
    //!=abstract
    public class MonAtelier extends Atelier {
    	
    	@Override
    	protected void executer(){
    	//!=abstract
    
    	}
    
    	@Override
    	protected boolean siExecutable(){
    	//!=abstract
    	
    	    return false;
    	}
    }
    
    • NOTE: une méthode abstraite peut être protected

    Impossible d’instancier une interface ou une classe abstraite #

    • On ne peut pas créer un objet à partir d’une interface ou d’une classe abstraite

    • P.ex. si on essaie d’instancier une classe abstraite:

    • P.ex. si on essaie d’instancier une interface:
    • Pour créer un objet qui remplit le contrat, il faut utiliser extends ou implements

    Quand utiliser une interface? #

    • Quand on veut faire la liste des méthodes publiques d’une classe

    • Typiquement, on utiliser une interface pour chaque thème: rouler, formater, manger

    • Une classe peut implanter plusieurs interfaces (c-à-d plusieurs implements):

    public class MonVehicule implements Rouleur, Formateur {
    
    	@Override
    	public void rouler(double kilometres){
    	}
    	
    	@Override
    	public String formater(){
    	    return null;
    	}
    
    	@Override
        public String formaterEnHtml(){
            return null;
        }
    }
    

    Interface et polymorphisme #

    • Une interface est aussi une façon d’accéder à un comportement restreint d’un objet

    • P.ex:

    public class Principal {
    
        public static void main(String[] args){
    
            Rouleur vehicule = new MonVehicule();
    
            // OK
            vehicule.rouler(10.0);
    
            // ERREUR
            System.out.println(vehicule.formater());
        }
    }
    
    • En utilisant la variable Rouleur vehicule (de type Rouleur), on dit:

      • j’ai seulement besoin des méthodes spécifiées dans Rouleur
      • les autres méthodes de Vehicule ne seront pas accessibles
    • Notre code est alors plus général et plus lisible:

      • on a rendu explicite le contrat qu’on utilise
      • n’importe quel objet qui implante Rouleur est compatible avec notre code
        • (et non uniquement les objets de type Vehicule)

    Quand utiliser une classe abtraite? #

    • Quand on veut obliger une sous-classe à redéfinir une méthode

    • Typiquement, cette méthode n’a pas de sens dans la classe parent

    • P.ex:

    public abstract class Vehicule extends Object implements Rouleur, Formateur {
    
    	protected abstract double consommationLitresParKilometre();
    
    	protected abstract String nomVehicule();
    
    	protected abstract boolean siNomFeminin();
    
    • Aucune des méthodes ci-haut n’a de sens dans Vehicule

      • il faut un type de véhicule en particulier (Auto, Moto) pour répondre
    • Mais on veut utiliser ces méthodes dans Vehicule, p.ex:

    	private double litresEssenceConsomes() {
    		return totalKilometres * consommationLitresParKilometre();
    	}
    
    • Alors la classe abstraite force les sous-classes à avoir ces méthodes

    • C’est le contrat de la classe abstraite

    Pourquoi ne pas toujours utiliser une classe abstraite? #

    • Parce que ce n’est pas permis en Java ;-)

    • Java ne supporte pas l’héritage multiple (c-à-d plusieurs extends)

    Creative Commons License Creative Commons Attribution Creative Commons ShareAlike
    • Théorie 1.2.4: interface, classe abstraite
      • Interface
      • Classe abstraite
      • Impossible d’instancier une interface ou une classe abstraite
      • Quand utiliser une interface?
      • Interface et polymorphisme
      • Quand utiliser une classe abtraite?
      • Pourquoi ne pas toujours utiliser une classe abstraite?