JavaRush /Blog Java /Random-FR /Pause café #90. 4 piliers de la programmation orientée ob...

Pause café #90. 4 piliers de la programmation orientée objet

Publié dans le groupe Random-FR
Source : The Geek Asian Jetons un coup d'œil aux quatre principes fondamentaux de la programmation orientée objet et essayons de comprendre comment ils fonctionnent. La programmation orientée objet (POO) est l'un des principaux paradigmes de programmation. Cela peut être facile et simple ou au contraire très complexe. Tout dépend de la manière dont vous décidez de développer votre application. Pause café #90.  4 piliers de la programmation orientée objet - 1Il y a 4 piliers de la POO :
  1. Encapsulation.
  2. Héritage.
  3. Abstraction.
  4. Polymorphisme.
Nous allons maintenant discuter de chacun d’eux avec une brève explication et un exemple de code réel.

1. Encapsulation

Nous avons tous étudié l'encapsulation en tant que masquage d'éléments de données et permettant aux utilisateurs d'accéder aux données à l'aide de méthodes publiques. Nous appelons ces getters et setters. Oublions cela et trouvons une définition plus simple. L'encapsulation est une méthode permettant d'empêcher l'utilisateur de modifier directement les données membres ou les variables de classe afin de maintenir l'intégrité des données. Comment faisons-nous cela? Nous limitons l'accès aux variables en basculant le modificateur d'accès sur privé et en exposant les méthodes publiques qui peuvent être utilisées pour accéder aux données. Examinons des exemples spécifiques ci-dessous. Cela nous aidera à comprendre comment utiliser l’encapsulation pour maintenir l’intégrité des données. Sans encapsulation :
/**
 * @author thegeekyasian.com
 */
public class Account {

  public double balance;

  public static void main(String[] args) {

  	Account theGeekyAsianAccount = new Account();

  	theGeekyAsianAccount.balance = -54;
  }
}
Dans l'extrait de code ci-dessus, la méthode main() accède directement à la variable balance . Cela permet à l'utilisateur de définir n'importe quelle valeur double à la variable de solde de la classe Account . Nous pouvons perdre l'intégrité des données en permettant à quiconque de régler le solde sur n'importe quel nombre invalide, tel que -54 dans ce cas. Avec encapsulation :
/**
 * @author thegeekyasian.com
 */
public class Account {

  private double balance;

  public void setBalance(double balance) {

    if(balance >= 0) { // Validating input data in order to maintain data integrity
	  this.balance = balance;
    }

    throw new IllegalArgumentException("Balance cannot be less than zero (0)");
  }

  public static void main(String[] args) {

  	Account theGeekyAsianAccount = new Account();

  	theGeekyAsianAccount.setBalance(1); // Valid input - Allowed
  	theGeekyAsianAccount.setBalance(-55); // Stops user and throws exception
  }
}
Dans ce code, nous avons restreint l'accès à la variable balance et ajouté une méthode setBalance() qui permet aux utilisateurs de définir la valeur du solde pour Account . Le setter vérifie la valeur fournie avant de l'attribuer à la variable. Si la valeur est inférieure à zéro, une exception est levée. Cela garantit que l’intégrité des données n’est pas compromise. Après avoir expliqué les exemples ci-dessus, j'espère que la valeur de l'encapsulation en tant que l'un des quatre piliers de la POO est claire.

2. Héritage

L'héritage est une méthode permettant d'obtenir des propriétés d'une autre classe partageant des caractéristiques communes. Cela nous permet d'augmenter la réutilisabilité et de réduire la duplication de code. La méthode a également le principe de l'interaction enfant-parent, lorsqu'un élément enfant hérite des propriétés de son parent. Examinons deux exemples rapides et voyons comment l'héritage rend le code plus simple et plus réutilisable. Sans héritage :
/**
 * @author thegeekyasian
 */
public class Rectangle {

  private int width;
  private int height;

  public Rectangle(int width, int height) {
	this.width = width;
	this.height = height;
  }

  public int getArea() {
	return width * height;
  }
}

public class Square {

  private int width; // Duplicate property, also used in class Rectangle

  public Square(int width) {
	this.width = width;
  }

  public int getArea() { // Duplicate method, similar to the class Rectangle
	return this.width * this.width;
  }
}
Les deux classes similaires partagent les propriétés width et la méthode getArea() . Nous pouvons augmenter la réutilisation du code en effectuant une petite refactorisation où la classe Square finit par hériter de la classe Rectangle . Avec héritage :
/**
 * @author thegeekyasian
 */
public class Rectangle {

  private int width;
  private int height;

  public Rectangle(int width, int height) {
	this.width = width;
	this.height = height;
  }

  public int getArea() {
	return width * height;
  }
}

public class Square extends Rectangle {

  public Square(int width) {
	super(width, width); // A rectangle with the same height as width is a square
  }
}
En étendant simplement la classe Rectangle , nous obtenons la classe Square en tant que type Rectangle . Cela signifie qu'il hérite de toutes les propriétés communes à Square et Rectangle . Dans les exemples ci-dessus, nous voyons comment l’héritage joue un rôle important pour rendre le code réutilisable. Cela permet également à une classe d'hériter du comportement de sa classe parent.

3. Abstraction

L'abstraction est une technique consistant à présenter uniquement les détails essentiels à l'utilisateur en masquant les détails inutiles ou non pertinents d'un objet. Cela permet de réduire la complexité opérationnelle du côté utilisateur. L'abstraction nous permet de fournir une interface simple à l'utilisateur sans demander de détails complexes pour effectuer une action. En termes simples, cela donne à l’utilisateur la possibilité de conduire une voiture sans avoir besoin de comprendre exactement comment fonctionne le moteur. Regardons d'abord un exemple, puis discutons de la façon dont l'abstraction nous aide.
/**
* @author thegeekyasian.com
*/
public class Car {

  public void lock() {}
  public void unlock() {}

  public void startCar() {

	checkFuel();
	checkBattery();
	whatHappensWhenTheCarStarts();
  }

  private void checkFuel() {
	// Check fuel level
  }

  private void checkBattery() {
	// Check car battery
  }

  private void whatHappensWhenTheCarStarts() {
	// Magic happens here
  }
}
Dans le code ci-dessus, les méthodes lock() , unlock() et startCar() sont publiques et les autres sont privées pour la classe. Nous avons facilité la tâche de l'utilisateur pour « conduire la voiture ». Bien sûr, il pourrait vérifier manuellement checkFuel() et checkBattery() avant de démarrer la voiture avec startCar() , mais cela ne ferait que compliquer le processus. Avec le code ci-dessus, tout ce que l'utilisateur doit faire est d'utiliser startCar() et la classe s'occupera du reste. C'est ce que nous appelons l'abstraction.

4. Polymorphisme

Le dernier et le plus important des quatre piliers de la POO est le polymorphisme. Le polymorphisme signifie « plusieurs formes ». Comme son nom l'indique, il s'agit d'une fonction qui permet d'effectuer une action de plusieurs manières ou différentes. Quand on parle de polymorphisme, il n’y a pas grand-chose à discuter à moins de parler de ses types. Il existe deux types de polymorphisme :
  1. Surcharge de méthode - polymorphisme statique (Static Binding).
  2. Remplacement de méthode - polymorphisme dynamique (Dynamic Binding).
Discutons de chacun de ces types et voyons quelle est la différence entre eux.

Surcharge de méthode - polymorphisme statique :

La surcharge de méthode ou polymorphisme statique, également connu sous le nom de liaison statique ou liaison au moment de la compilation, est un type dans lequel les appels de méthode sont déterminés au moment de la compilation. La surcharge de méthodes nous permet d'avoir plusieurs méthodes portant le même nom, ayant différents types de données de paramètres, ou différents nombres de paramètres, ou les deux. Mais la question est : pourquoi la surcharge de méthode (ou polymorphisme statique) est-elle utile ? Examinons les exemples ci-dessous pour mieux comprendre la surcharge de méthodes. Sans surcharge de méthode :
/**
* @author thegeekyasian.com
*/
public class Number {

  public void sumInt(int a, int b) {
	System.out.println("Sum: " + (a + b));
  }

  public void sumDouble(double a, double b) {
	System.out.println("Sum: " + (a + b));
  }

  public static void main(String[] args) {

	Number number = new Number();

	number.sumInt(1, 2);
	number.sumDouble(1.8, 2.5);
  }
}
Dans l'exemple ci-dessus, nous avons créé deux méthodes avec des noms différents, uniquement pour ajouter deux types de nombres différents. Si nous continuons avec une implémentation similaire, nous aurons plusieurs méthodes avec des noms différents. Cela réduira la qualité et la disponibilité du code. Pour améliorer cela, nous pouvons utiliser la surcharge de méthodes en utilisant le même nom pour différentes méthodes. Cela permettra à l'utilisateur d'avoir une option comme point d'entrée pour additionner différents types de nombres. La surcharge de méthodes fonctionne lorsque deux méthodes ou plus ont le même nom mais des paramètres différents. Le type de retour peut être identique ou différent. Mais si deux méthodes ont le même nom, les mêmes paramètres, mais des types de retour différents, alors cela provoquera une surcharge et une erreur de compilation ! Avec surcharge de méthode :
/**
* @author thegeekyasian.com
*/
public class Number {

  public void sum(int a, int b) {
	System.out.println("Sum: " + (a + b));
  }

  public void sum(double a, double b) {
	System.out.println("Sum: " + (a + b));
  }

  public static void main(String[] args) {

	Number number = new Number();

	number.sum(1, 2);
	number.sum(1.8, 2.5);
  }
}
Dans le même code, avec quelques modifications mineures, nous avons pu surcharger les deux méthodes, en rendant les noms identiques pour les deux. L'utilisateur peut désormais spécifier ses types de données spécifiques comme paramètres de méthode. Il effectuera ensuite une action en fonction du type de données qui lui est fourni. Cette liaison de méthode est effectuée au moment de la compilation car le compilateur sait quelle méthode sera appelée avec le type de paramètre spécifié. C'est pourquoi nous appelons cela une liaison au moment de la compilation.

Remplacement de méthode - polymorphisme dynamique :

Contrairement à la surcharge de méthodes, la substitution de méthode vous permet d'avoir exactement la même signature que plusieurs méthodes, mais elles doivent appartenir à plusieurs classes différentes. La question est : qu’a-t-il de si spécial ? Ces classes ont une relation IS-A, c'est-à-dire qu'elles doivent hériter les unes des autres. En d’autres termes, dans le cas du remplacement de méthode ou du polymorphisme dynamique, les méthodes sont traitées dynamiquement au moment de l’exécution lorsque la méthode est appelée. Cela se fait en fonction de la référence à l'objet avec lequel il est initialisé. Voici un petit exemple de substitution de méthode :
/**
* @author thegeekyasian.com
*/
public class Animal {

  public void walk() {
	System.out.println("Animal walks");
  }
}

public class Cat extends Animal {

  @Override
  public void walk() {
	System.out.println("Cat walks");
  }
}

public class Dog extends Animal {

  @Override
  public void walk() {
	System.out.println("Dog walks");
  }
}

public class Main {

  public static void main(String[] args) {

	Animal animal = new Animal();
	animal.walk(); // Animal walks

	Cat cat = new Cat();
	cat.walk(); // Cat walks

	Dog dog = new Dog();
	dog.walk(); // Dog walks

	Animal animalCat = new Cat(); // Dynamic Polymorphism
	animalCat.walk(); // Cat walks

	Animal animalDog = new Dog(); // Dynamic Polymorphism
	animalDog.walk(); //Dog walks
  }
}
Dans cet exemple primordial, nous avons attribué dynamiquement des objets de type « Chien » et « Chat » au type « Animal ». Cela nous permet d'appeler dynamiquement la méthode walk() sur les instances référencées au moment de l'exécution. Nous pouvons le faire en utilisant le remplacement de méthode (ou le polymorphisme dynamique). Ceci conclut notre brève discussion sur les quatre piliers de la POO et j'espère que vous la trouverez utile.
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION