RunUO-FR
Vous souhaitez réagir à ce message ? Créez un compte en quelques clics ou connectez-vous pour continuer.
RunUO-FR

Forum de support pour RunUO en français.
 
AccueilAccueil  Dernières imagesDernières images  RechercherRechercher  S'enregistrerS'enregistrer  Connexion  
Le Deal du moment : -15%
(Adhérents) LEGO® Icons 10318 Le Concorde
Voir le deal
169.99 €

 

 Les interfaces

Aller en bas 
AuteurMessage
Gargouille




Messages : 97
Date d'inscription : 02/09/2008

Les interfaces Empty
MessageSujet: Les interfaces   Les interfaces Icon_minipostedSam 20 Sep - 14:56

En C#, pas d'héritage multiple.

L'héritage est une chaîne en droite ligne.

Parfois cependant il pourrait être utile que des classes séparées dans l'arbre d'héritage puissent partager un même bagage.

C'est un peu le rôle des interfaces, qui définissent un bagage commun de façon "transversale", indépendament de la notion d'héritage.

Un exemple dans RunUO : les classes Mobile et Item définissent toutes deux une variable Location de type Point3D (donc un ensemble de trois int formant les coordonnées x,y et z)...

Lorsque par exemple après une Target, on reçoit une instancde object, il nous faut faire les tests if(obj is Mobile) else if (obj is Item) avant de pouvoir s'adresser à mob.Location ou a item.Location...

Ici c'est simple, on n'a que deux classes différentes, mais on pourrait en avoir 36...

Une autre façon de faire est de caster l'object reçu en un objet de type IPoint3D, c'est à dire un objet défini en tant qu'interface.
C'est possible dans RunUO car Mobile et Item déclarent tous deux l'interface IPoint3D...
Code:
public class Mobile : IEntity, IPoint3D, IHued, IComparable, IComparable<Mobile>, ISerializable
Code:
public class Item : IPoint3D, IEntity, IHued, IComparable, IComparable<Item>, IComparable<IEntity>, ISerializable

A partir de là, il est possible de faire :
Code:

if(obj is IPoint3D)
{
IPoint3D point = (IPoint3D)obj;
}

On peut donc manipuler cet objet, indépendament de sa nature, Item ou Mobile, en le définissant par rapport à ce que ces deux classes, d'héritage différent, ont en commun grâce à cette interface.

Ensuite, dans les fichiers source, voici comment est définie l'interface IPoint3D (et donc IPoint2D) :
Code:
public interface IPoint2D
   {
      int X{ get; }
      int Y{ get; }
   }

   public interface IPoint3D : IPoint2D
   {
      int Z{ get; }
   }

A partir de là,on sait que l'objet point définit X,Y et Z que l'on peut utiliser pour définir un new Point3D.

L'interface est un objet, mais n'est pas défini avec le mot clef class, mais interface.
Ce qui est déclaré dans le corps de l'interface est tout ce qui doit être commun aux différentes classes qui déclareront l'interface dans leur héritage.

Une classe qui déclarerait IPoint3D, sans déclarer de propriété X, Y et Z ne compilerait pas.


La déclaration d'une interface est l'assurance que la classe obéit bien aux spécifications déclarées dans l'interface, et peut donc par conséquent être castées dans le type de l'interface.


Un autre exemple dans RunUO, l'interface ICraftable.
Les items craftables sont tout simplement ceux qui sont scriptés dans les classes def du craftsystem (DefAlchemy, DefBlacksmithy, etc...). Pas besoin de l'interface.

L'interface sert uniquement à appeler l'objet à sa création pour un comportement particulier.

Voici la déclaration de l'interface :
Code:

public interface ICraftable
   {
      int OnCraft( int quality, bool makersMark, Mobile from, CraftSystem craftSystem, Type typeRes, BaseTool tool, CraftItem craftItem, int resHue );
   }

Donc, toutes les classes déclarant ICraftable doivent déclarer une méthode OnCraft de type int qui attend ces arguments.

A partir de là, dans CraftItem, lorsque l'item est créé on a :
Code:

if( item is ICraftable )
endquality = ((ICraftable)item).OnCraft( quality, makersMark, from, craftSystem, typeRes, tool, this, resHue );

La méthode OnCraft de l'item est donc appelée, ici pour calculer un int pour la variable Quality, alors qu'on ne sait pas de quel type d'item il s'agit.

On aurait pu s'en passer en déclarant OnCraft par défault dans Item, mais on n'aura des OnCraft que dans les items qui le nécessitent, sans être obligé dans le code appelant de déclarer des dizaines de if(item is truc) if(item is machin) etc...

Et donc dans le OnCraft de chaque objet, on met le comportement qu'on veut...
Revenir en haut Aller en bas
 
Les interfaces
Revenir en haut 
Page 1 sur 1

Permission de ce forum:Vous ne pouvez pas répondre aux sujets dans ce forum
RunUO-FR :: Tutoriaux Scripts :: Tutoriaux C#-
Sauter vers: