En C #, lorsque j'ai une interface et plusieurs implémentations concrètes, puis-je convertir l'interface en un type concret ou le type concret est-il converti en interface?
Quelles sont les règles dans ce cas?
Les deux directions sont autorisées en Java et en C #. Le downcasting nécessite une conversion explicite et peut générer une exception si l'objet n'est pas du type correct. Cependant, la diffusion en amont ne nécessite aucune diffusion explicite et est toujours sûre.
En d’autres termes, en supposant que vous avez public interface Animal
et deux implémentations de cette interface
, Cat
et Dog
....
Animal meowAnimal = new Cat(); // No cast required
Animal barkAnimal = new Dog(); // No cast required
Cat myCat = (Cat) meowAnimal; // Explicit cast needed
Dog myDog = (Dog) barkAnimal; // Explicit cast needed
Dog myPet = (Dog) meowAnimal; // Will compile but throws an Exception
et vous voudrez une try
/catch
autour des conversions explicites. En C #, vous avez le mot clé as
utile:
Dog myDog = barkAnimal as Dog;
Dog myPet = meowAnimal as Dog;
Aucune exception ne sera levée et myDog sera non Null et myPet sera null. Java n'a pas de mot clé équivalent, bien que vous puissiez toujours utiliser les tests if (meowAnimal instanceof Dog)
pour préserver la sécurité du type. (J'imagine que le mot clé "as
" génère un bytecode qui échoue si, l'attribution de la valeur null à is
échoue. Mais peut-être .NET possède-t-il une instruction bytecode qui équivaut à "as
".
Dans la plupart des langues, vous pouvez lancer les deux directions. Si vous avez une classe concrète, vous pouvez la lancer dans l'interface. Si vous avez une interface, il est possible de transtyper vers la classe concrète.
Généralement, vous voulez seulement aller dans la première direction. La raison en est que vous ne devriez pas savoir ce qu'est la classe concrète lorsque vous n'avez qu'un pointeur sur l'interface. Si vous transmettez quelque chose en tant qu'interface, vous devriez pouvoir faire tout ce dont vous avez besoin à partir de cette interface. Si vous vous trouvez dans l'obligation d'utiliser des parties de l'objet concret qui ne sont pas sur l'interface, vous rencontrez un problème de conception qui doit être résolu au lieu d'être moulé.
Si vous parlez de Java (mais les règles pour les autres langages sont similaires), c'est comme ça:
Vous pouvez créer une interface vers une implémentation concrète (si elle est en réalité une référence à une implémentation concrète spécifique). Cela signifie
Vehicle v=new Car();
(Car)v // this is OK
(Bus)v // this is not
L'erreur se manifeste par ClassCastException
en Java.
Vous pouvez librement convertir librement une implémentation concrète d'une interface.
Les deux sont valides, considérant qu'il s'agit d'une distribution logique. Souvent, vos utilisateurs d’interface n’ont pas accès aux classes concrètes, ce qui est une des principales raisons d’avoir une interface en premier lieu.
Une interface can est toute la classe, mais n’a pas besoin de be, il est préférable de créer un constructeur qui accepte l’interface en tant que paramètre et de copier les paramètres. ce qui se passe et ce qui est nécessaire.