Les
classes scellées sont une fonctionnalité qui a été précédemment introduite dans le JDK 15 et formellement dans le JDK 17. Une classe scellée est une classe qui ne peut pas être étendu par des classes qui ne sont pas explicitement autorisées (dans la déclaration de classe), le nombre de sous-classes est donc limité et connu à l'avance.
Ils sont destinés à permettre un contrôle plus précis de la hiérarchie d'héritage, ainsi qu'à faciliter la modélisation de domaines où toutes les sous-classes possibles sont connues, et à améliorer la sécurité et la maintenabilité du code.
La différence entre une classe scellée et une classe du type final est que cette dernière ne peut être étendue par aucune classe, alors qu'une classe scellée peut être étendue par un nombre limité de cours.
Supposons que nous ayons deux classes, une classe Shape et une classe Circle, les deux sont des classes normales, donc Shape peut être étendu par n'importe quelle classe.
public class Shape { // ... } public class Circle extends Shape { // ... }
Si nous utilisons le mot-clé final dans la classe Shape, alors il ne peut être étendu par aucune classe.
public final class Shape { // ... } public class Circle extends Shape { // Error // ... }
Maintenant, si nous voulons que la classe Shape soit étendue uniquement par certaines classes (par exemple, Circle et Square), alors nous pouvons la déclarer comme une classe scellée.
public sealed class Shape permits Circle, Square { // ... }
En analysant la déclaration précédente, on voit qu'il faut placer scellé avant le mot classe pour indiquer qu'il s'agit d'une classe scellée. Ensuite, le mot permits est utilisé suivi d'une liste de classes pouvant étendre la classe actuelle, dans l'exemple ci-dessus, seules les classes Circle et Square peuvent étendre la classe Shape.
La même chose se produit si vous travaillez avec une classe de type abstrait, c'est-à-dire une classe qui ne peut pas être instanciée, mais qui peut être étendue par d'autres classes.
public sealed abstract class Shape permits Circle, Square { // ... }
Ce concept peut également s'appliquer aux interfaces.
public sealed interface Shape permits Circle, Square { // ... }
Remarque : Les sous-classes autorisées doivent se trouver dans le même module ou package que la classe scellée, sinon un message d'erreur s'affichera.
Une fois qu'une classe a été déclarée scellée et que les classes autorisées ont été spécifiées, lors de l'extension de la classe Shape avec une classe autorisée (en plaçant extends Shape), l'IDE affichera un message d'erreur similaire à celui-ci Modificateur 'sealed' , 'non scellé' ou 'final' attendu, Qu'est-ce que cela signifie ?.
Il faut prendre en considération que chacune des classes (sous-classes) autorisées doit être déclarée avec l'un des mots-clés suivants :
Pour mettre ce qui précède en pratique, travaillons avec la classe Shape et les classes Circle, Square et Triangle pour voir comment les classes autorisées peuvent être déclarées selon ce qui a été mentionné ci-dessus.
public class Shape { // ... } public class Circle extends Shape { // ... }
Si l'on veut que la classe Circle soit du type final et par conséquent ne puisse être étendue, alors il faut la déclarer comme suit :
public final class Shape { // ... } public class Circle extends Shape { // Error // ... }
Cela empêche la classe Circle d'être étendue par une autre classe.
Si nous voulons que la classe Square soit de type scellé et avons autorisé les sous-classes qui peuvent l'étendre, alors elle doit être déclarée comme suit :
public sealed class Shape permits Circle, Square { // ... }
Pour cet exemple, chacune des classes autorisées (SquareChild1 et SquareChild2) sont déclarées de type final afin qu'elles ne puissent être étendues par aucune autre classe.
public sealed abstract class Shape permits Circle, Square { // ... }
Si vous souhaitez que ces classes puissent être étendues par plus de classes, alors elles doivent être déclarées comme scellées ou qu'elles puissent être étendues par n'importe quelle classe non scellée.
Dans le cas de la classe Triangle, lorsqu'elle est déclarée non scellée, elle permet d'étendre cette classe par n'importe quelle autre classe, sans qu'il soit nécessaire de préciser les classes autorisées.
public sealed interface Shape permits Circle, Square { // ... }
Par exemple, si vous créez la classe TriangleChild qui étend Triangle, aucun message d'erreur ne s'affichera.
public sealed class Shape permits Circle, Square, Triangle { // ... }
À ce stade, il est important de considérer que si vous déclarez une classe comme non scellée, vous "brisez" d'une certaine manière le but des classes scellées, puisqu'elle permet à cette classe d'être étendue par n'importe quelle autre classe et le nombre de sous-classes autorisées n'est pas limité.
De son côté, un enregistrement ne peut pas être du type scellé puisqu'il est déjà du type final et ne peut être étendu par aucune autre classe. Mais ce que vous pouvez faire, c'est déclarer un enregistrement comme autorisé dans une interface du type scellé (considérez qu'un enregistrement ne peut pas étendre une classe, seulement implémenter des interfaces). Par exemple, si vous avez un enregistrement appelé Rectangle et une interface Shape de type scellé, vous pouvez déclarer Rectangle comme autorisé dans l'interface Shape et de cette manière, Rectangle pourra implémenter l'interface Shape et toutes les méthodes que cette interface contient.
public class Shape { // ... } public class Circle extends Shape { // ... }
Si une classe déclarée scellée possède des classes internes (classes imbriquées ou internes), on suppose que ces classes appartiennent à la classe principale et, par conséquent, il n'est pas nécessaire de les déclarer comme autorisées. Par exemple, si vous avez la classe Animal déclarée comme scellée et qu'en même temps elle a Dog et Cat comme classes internes, ces classes n'ont pas besoin d'être déclarées comme autorisées, mais elles doivent étendre la classe principale et être du type final. , scellé ou non scellé.
public final class Shape { // ... } public class Circle extends Shape { // Error // ... }
Les classes scellées sont un moyen de limiter une hiérarchie de classes à un nombre fini de sous-classes autorisées, même si nous avons vu que si une classe est déclarée non scellée, le but est quelque peu perdu ou en déclarant un sous-classe comme scellée, vous pouvez étendre cette hiérarchie encore plus loin.
Il est important de considérer que lorsque l'on déclare une classe comme scellée, cela fait uniquement référence à qui peut l'étendre, mais ne limite pas la création d'instances de la classe principale, ni ne modifie la sémantique de la classe, c'est-à-dire cela ne modifie pas le comportement interne de la classe.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!