Les différents types de fonctions
Les méthodes sont des fonctions définies à l’intérieur d’une classe, permettant de manipuler les données de l’objet et d’interagir avec d’autres objets. Elles constituent le comportement des objets et facilitent la communication entre eux. En programmation orientée objet, il existe plusieurs types de méthodes : les méthodes d’instance, les méthodes de classe, les propriétés (getter et setter) et les fonctions utilitaires.
Lorsqu’on crée une classe, il est nécessaire de choisir avec soin les types de méthodes à utiliser. Il faut bien comprendre quand opter pour des méthodes d’instance, des méthodes de classe, des propriétés ou des fonctions utilitaires. Chaque méthode doit être adaptée à sa fonction spécifique pour éviter de mélanger les différents types, ce qui pourrait compliquer la conception et la maintenance du code. Utiliser correctement chaque type de méthode aide à garder le code organisé et facile à gérer.
Il faut ainsi choisir judicieusement entre les méthodes d’instance, les méthodes de classe, les propriétés et les fonctions utilitaires pour obtenir un design de code clair et cohérent. Une solide compréhension de ces concepts est nécessaire pour s’assurer que les responsabilités sont correctement réparties entre les différentes parties du code, ce qui facilite la lisibilité, la modularité et la réutilisabilité. Il faut donc prendre le temps de bien comprendre ces concepts pour concevoir un code robuste et évolutif.
Les méthodes d’instances
Les méthodes d’instance sont des fonctions qui agissent sur les données d’un objet spécifique (instance) de la classe. Elles ont accès à toutes les propriétés et méthodes de l’objet. Par exemple, une méthode d’instance pour une classe Employé
pourrait être calculer_indexation_salaire
, qui agirait sur le salaire d’un employé particulier selon son ancienneté.
class Employe: nombre_employes = 0 def __init__(self, salaire, adresse): self.__salaire = salaire self.__adresse = adresse self.__anciennete = 0 Employe.nombre_employes += 1 def calculer_indexation_salaire(self): self.__anciennete += 1 self.__salaire = self.__salaire + self.__salaire * self.__anciennete/100
class Employe { public: static int nombre_employes; Employe(double salaire, std::string adresse) : _salaire(salaire), _adresse(adresse), _anciennete(0) { nombre_employes++; } void calculer_indexation_salaire() { _anciennete++; _salaire = _salaire + _salaire * _anciennete / 100; } private: double _salaire; std::string _adresse; int _anciennete; }; int Employe::nombre_employes = 0;
public class Employe { public static int NombreEmployes = 0; private double _salaire; private string _adresse; private int _anciennete; public Employe(double salaire, string adresse) { _salaire = salaire; _adresse = adresse; _anciennete = 0; NombreEmployes++; } public void CalculerIndexationSalaire() { _anciennete++; _salaire = _salaire + _salaire * _anciennete / 100.0; } }
Les méthodes statiques
Les méthodes de classe, également appelées méthodes statiques, sont des fonctions qui appartiennent à la classe elle-même plutôt qu’à une instance. Elles sont généralement utilisées pour effectuer des opérations qui ne dépendent pas de propriétés d’un objet particulier, mais liées à la classe dans son ensemble. Par exemple, une méthode de classe pour une classe Employé
pourrait être nombre_total_employés
, qui ne dépend pas de propriétés d’une instance spécifique d’employé, mais plutôt du nombre total d’employés créés à partir de cette classe.
Dans l’exemple suivant, observez la spécificité du choix de déclaration pour la variable “nombre_employes
“, qui est en réalité elle aussi statique. Comme les méthodes statiques, les variables statiques sont liées à la classe et non à une instance spécifique. Ainsi, la valeur de cette variable est commune à toutes les instances de la classe.
class Employe: nombre_employes = 0 def __init__(self, salaire, adresse): self.__salaire = salaire self.__adresse = adresse self.__anciennete = 0 Employe.nombre_employes += 1 @staticmethod def nombre_total_employes(): return Employe.nombre_employes
class Employe { public: static int nombre_employes; Employe(double salaire, std::string adresse) : _salaire(salaire), _adresse(adresse), _anciennete(0) { nombre_employes++; } static int nombre_total_employes() { return nombre_employes; } private: double _salaire; std::string _adresse; int _anciennete; };
public class Employe { public static int NombreEmployes = 0; private double _salaire; private string _adresse; private int _anciennete; public Employe(double salaire, string adresse) { _salaire = salaire; _adresse = adresse; _anciennete = 0; NombreEmployes++; } public static int NombreTotalEmployes() { return NombreEmployes; } }
Les propriétés
Nous l’avons vu précédemment dans le chapitre de l’encapsulation : les propriétés sont des méthodes spéciales, souvent appelées getter et setter, qui permettent d’accéder et de modifier les données privées d’un objet de manière contrôlée. Les getters sont utilisés pour récupérer la valeur d’une propriété, tandis que les setters permettent de définir une nouvelle valeur pour la propriété. L’utilisation de getters et setters est une bonne pratique pour assurer l’encapsulation et protéger les données internes de l’objet.
Les fonctions utilitaires
Les fonctions utilitaires sont des fonctions qui servent à effectuer des opérations générales et qui ne sont pas directement liées à la logique d’un objet ou d’une classe spécifique. Lorsqu’une fonction utilitaire n’est pas propre à la logique d’un objet (ni public, ni privé), elle ne doit pas faire partie de la classe. Un exemple de fonction utilitaire liée à la classe Employé
pourrait être une fonction calculer_distance_entre_deux_adresses
, qui prendrait en entrée les adresses de deux employés et renverrait la distance entre elles. Cette fonction ne dépend pas directement de la logique spécifique d’un employé ou de ses propriétés, mais elle peut être utile pour gérer des opérations courantes liées aux employés.
def calculer_distance_entre_deux_adresses(addr1: str, addr2: str) return abs(len(addr1) - len(addr2)) class Employe: nombre_employes = 0 def __init__(self, salaire: int, adresse: str): self.__salaire = salaire self.__adresse = adresse self.__anciennete = 0 Employe.nombre_employes += 1
int calculer_distance_entre_deux_adresses(const std::string& addr1, const std::string& addr2) { return std::abs(static_cast<int>(addr1.length()) - static_cast<int>(addr2.length())); } class Employe { public: static int nombre_employes; Employe(int salaire, const std::string& adresse) : _salaire(salaire), _adresse(adresse), _anciennete(0) { nombre_employes++; } private: int _salaire; std::string _adresse; int _anciennete; }; int Employe::nombre_employes = 0;
public static class Utils { public static int CalculerDistanceEntreDeuxAdresses(string addr1, string addr2) { return Math.Abs(addr1.Length - addr2.Length); } } public class Employe { public static int NombreEmployes = 0; private int _salaire; private string _adresse; private int _anciennete; public Employe(int salaire, string adresse) { _salaire = salaire; _adresse = adresse; _anciennete = 0; NombreEmployes++; } }