web-dev-qa-db-fra.com

Interface cast vers son objet concret de mise en œuvre ou vice versa?

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?

35
dotnetdev

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".

43
Eddie

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é.

14
Steve Rowe

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.

3
jpalecek

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.

0
BC.

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.

0
Walter Verhoeven