Déclaration des interfaces et leur implémentation au sein d'une classe

Résolu
eishtein Messages postés 52 Date d'inscription dimanche 6 décembre 2009 Statut Membre Dernière intervention 23 janvier 2014 - 4 avril 2011 à 10:38
krimog Messages postés 1860 Date d'inscription lundi 28 novembre 2005 Statut Membre Dernière intervention 14 février 2015 - 7 avril 2011 à 13:38
bonjour les gars;
je suis un développeur en programmation orientée objet et je suis en cours d'apprentissage du langage 'c#'. Cependant, il me reste à savoir comment implémenter une interface au sein d'une classe. C'est pourquoi je vous serais reconnaissant de me donner un coup de main pour mieux comprendre ce concept.
ET MERCI D'AVANCE
EISHTEIN

11 réponses

krimog Messages postés 1860 Date d'inscription lundi 28 novembre 2005 Statut Membre Dernière intervention 14 février 2015 49
4 avril 2011 à 11:41
Salut

C'est on-ne-peut-plus simple :
D'abord, tu crées ton interface :

public interface Machin
{
    public void truc();
    public int bidule(string chose);
}


Ensuite, tu indiques qu'une classe l'implémentes avec la même syntaxe qu'un héritage :
public class MaClasse : Machin
{
}


Enfin, tu implémentes les méthodes. Si tu utilises Visual Studio, c'est très simple à faire : tu cliques-droit sur l'interface dans la déclaration de ta classe, tu fais "Implémenter l'interface" puis à nouveau "Implémenter l'interface".
public class MaClasse : Machin
{
    public void truc()
    {
        throw new NotImplementedException();
    }

    public int bidule(string chose)
    {
        throw new NotImplementedException();
    }
}

Tu as juste à créer des méthodes de même prototype, pas besoin de mot-clé.

Pendant qu'on y est, voici un petit point sur l'héritage et les classes abstraites :
public abstract class MaClasseAbstraite
{
    public abstract void Methode1();
    public virtual int Methode2(int i)
    {
        return i * i;
    }
    public int Methode3(int i)
    {
        return i * 2;
    }
}

public class MaClasseFille : MaClasseAbstraite
{
    public override void Methode1()
    {
        Console.WriteLine("Hello World");
    }

    public override int Methode2(int i)
    {
        return base.Methode2(i) * i;
    }

    public new int Methode3(int i)
    {
        return i * 3;
    }
}

Le mot-clé "abstract" est utilisé à la fois pour les classes et pour les méthodes. Le mot clé "vitual" indique que la méthode peut être substituée. Lors de l'utilisation de ces deux mots-clé, l'implémentation ou la substitution doit avoir le modificateur "override" dans la classe fille.
Le modificateur "new", utilisé dans Methode3 de MaClasseFille, permet de redéfinir la méthode pour la classe actuelle, mais ce n'est pas une substitution (cf exemple ci-dessous). En revanche, la méthode mère n'a pas besoin d'un modificateur particulier.

MaClasseFille objet = new MaClasseFille();
objet.Methode1(); // Affiche "Hello World"
objet.Methode2(2); // Renvoie 8, puisque Methode2 a été substituée
objet.Methode3(2); // Renvoie 6, puisque Methode3 a été redéfinie
// Jusque là, normal
MaClasseAbstraite objet2 = (MaClasseAbstraite)objet;
objet2.Methode1(); // Affiche "Hello World"
objet2.Methode2(2); // Renvoie 8, puisque Methode2 a été substituée
objet2.Methode3(2); // Renvoie 4 !!!

Lorsqu'une méthode est redéfinie avec le mot-clé "new", la nouvelle définition n'est appelée QUE si l'objet est considéré comme un objet de la classe redéfinissant la méthode (en l'occurrence "MaClasseFille"). Or, cet objet ("objet2"), dans ce code, est considéré comme un objet de type "MaClasseAbstraite". Il ne prend donc pas en compte la redéfinition.

Krimog : while (!(succeed = try())) ;
- Nous ne sommes pas des décodeurs ambulants. Le style SMS est prohibé. -
3
krimog Messages postés 1860 Date d'inscription lundi 28 novembre 2005 Statut Membre Dernière intervention 14 février 2015 49
4 avril 2011 à 14:12
Ça aidera si tu indiques quel est ce message d'erreur.

"faire référence à une interface (plus précisément un fichier DLL)" = > Une DLL peut contenir des interfaces, mais une DLL n'est pas une interface.

As-tu bien pensé à déclarer le namespace ?
Soit
using [Namespace à utiliser] ;
en haut de ton fichier, soit
[Namespace à utiliser].TaClasse

Krimog : while (!(succeed = try())) ;
- Nous ne sommes pas des décodeurs ambulants. Le style SMS est prohibé. -
3
eishtein Messages postés 52 Date d'inscription dimanche 6 décembre 2009 Statut Membre Dernière intervention 23 janvier 2014
4 avril 2011 à 12:36
merci pour la réponse, mais le problème c'est que je veux, dans un projet, faire référence à une interface (plus précisément un fichier DLL)--> quand je fais appel à une fonction de ce fichier==> oop , un message d'erreur
et c'est ce qui m'énerve en fin de compte
merci encore une fois pour ta première réponse
0
eishtein Messages postés 52 Date d'inscription dimanche 6 décembre 2009 Statut Membre Dernière intervention 23 janvier 2014
5 avril 2011 à 08:30
merci encore une fois pour la réponse;
je ne sais pas pourquoi, mais c'est comme si on ma condamné à ne pas utiliser des directives import au sein de la classe où je doit utiliser les fcts DLL
mes remerciements, Krimog ^^
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
krimog Messages postés 1860 Date d'inscription lundi 28 novembre 2005 Statut Membre Dernière intervention 14 février 2015 49
5 avril 2011 à 10:28
On a vraiment besoin de connaître ton erreur exacte si tu veux qu'on puisse t'aider plus.

Krimog : while (!(succeed = try())) ;
- Nous ne sommes pas des décodeurs ambulants. Le style SMS est prohibé. -
0
eishtein Messages postés 52 Date d'inscription dimanche 6 décembre 2009 Statut Membre Dernière intervention 23 janvier 2014
6 avril 2011 à 09:46
ben en fait l'idée est de déclarer une méthode prenant comme arguments n'importe quelle classe prenant en charge une interface 'X',que je la lance dans la méthode Main() et que je vois les résultats appropriés de la classe
-->je rappelle que cette methode retourne un ToString()
@++
eishtein
"NO SACRIFICE...NO VICTORY"
0
krimog Messages postés 1860 Date d'inscription lundi 28 novembre 2005 Statut Membre Dernière intervention 14 février 2015 49
6 avril 2011 à 10:21
Je comprends bien ce que tu essaies de faire (c'est bien à ça que sert une interface), mais tu dis dans ton deuxième message "oop , un message d'erreur", et il nous faudrait le texte exact de ce message d'erreur afin qu'on puisse avoir une idée d'où vient le problème.

Krimog : while (!(succeed = try())) ;
- Nous ne sommes pas des décodeurs ambulants. Le style SMS est prohibé. -
0
eishtein Messages postés 52 Date d'inscription dimanche 6 décembre 2009 Statut Membre Dernière intervention 23 janvier 2014
7 avril 2011 à 06:51
le type d'erreur qu'envoie le compilateur est du genre: "impossible de convertir une classe de type X en un string"...enfin, quelque chose de ce genre, comme quoi il est impossible de retourner un ToString() d'une classe par l'intermediaire de cette fct....
@++
0
krimog Messages postés 1860 Date d'inscription lundi 28 novembre 2005 Statut Membre Dernière intervention 14 février 2015 49
7 avril 2011 à 11:19
ToString() est une méthode de System.Object, classe que dérive tout objet (instance de classe ou structure). Donc tu peux TOUJOURS faire un ToString() sur un objet non null.

En revanche, si une méthode demande un string en paramètre, il faut appeler explicitement la méthode ToString().

public void Methode(string parametre)
{
//...
}

IMonInterface monObjet = new MaClasse(); // MaClasse implémente IMonInterface
Methode(monObjet); // Provoque une erreur qui dit que monObjet n'est pas de type string
Methode(monObjet.ToString()); // Fonctionne


Krimog : while (!(succeed = try())) ;
- Nous ne sommes pas des décodeurs ambulants. Le style SMS est prohibé. -
0
eishtein Messages postés 52 Date d'inscription dimanche 6 décembre 2009 Statut Membre Dernière intervention 23 janvier 2014
7 avril 2011 à 13:13
voici texto le code ainsi que l'erreur générée avec:



//directives 'using':
using System;
using System.Data.Common;

//espace de nom courant 'traffic':
namespace traffic
{
//les sous-directives de l'espace de nom:
using Ch09Ex03;
using VEHICLES;
using System.Runtime.InteropServices;
//classe de production du message:


class l
{



//declaration des fonctions externes utilisant les fcts DLL

class Program
{
[DllImport("vehicles.dll")]
public static extern void f(VEHICLES.IPassengerCarrier A)
{

}
//importation du fichier DLL:
public static void Main(string[] args)
{
Console.WriteLine("Hello World!");
Train A=new Train();
Console.Write(f(A.ToString()));
Console.ReadKey(true);
}
}



}

}
'traffic.l.Program.f(VEHICLES.IPassengerCarrier)' ne peut pas être extern et être déclaré (CS0179) - C:\Documents and Settings\Administrateur\Mes documents\benhsain\benhsain-c#\traffics\traffic\traffic\Program.cs:25,29
0
krimog Messages postés 1860 Date d'inscription lundi 28 novembre 2005 Statut Membre Dernière intervention 14 février 2015 49
7 avril 2011 à 13:38
Tu aurais dû préciser que ta DLL n'était pas une DLL .net...
(Ou alors, si c'est réellement une DLL .net, il ne faut pas mettre [DllImport] ni la fonction f)

L'erreur est assez parlante. Ta fonction f() est à la fois extern et déclarée.
Il est normal qu'elle soit extern si tu importes celle d'une DLL, mais il ne faut pas la déclarer, c'est à dire qu'il ne fait pas mettre { } (sinon il croit que tu veux redéfinir cette méthode avec un contenu vide).
Il suffit d'indiquer le prototype de ta méthode, c'est à dire avec ; à la fin, sans accolades.
=>
public static extern void f(VEHICLES.IPassengerCarrier A);


Krimog : while (!(succeed = try())) ;
- Nous ne sommes pas des décodeurs ambulants. Le style SMS est prohibé. -
0
Rejoignez-nous